Glassfish, EJB Load balancing - glassfish

I'm having a problem with ejb load balancing inside glassfish 3 cluster.
I have one ear project witch contains EJB module and WEB module. All my EJB's are stateless and remote in EJB module. In WEB module I have one servlet which suppose to lookup for ejb and print on which instance in cluster he get ejb.
I'm calling EJB from servlet like this:
Properties props = System.getProperties();
props.setProperty("com.sun.appserv.iiop.endpoints", "10.8.10.202:23700,10.8.10.203:23700,10.8.10.204:23700,10.8.10.205:23700");
InitialContext ic = new InitialContext();
EJBRemote ejb = (EJBRemote) ic.lookup("java:global/app-name-ear/app-ejbs/EJB!com.tt.EJBRemote");
Problem is that my request always ends up on first instance of 4 possible.
How I can achieve load balancing in my case? Do I need stand alone client (web-app in separate project)? How glassfish cluster knows that there are another instances where my servlet can lookup for EJB?

Your issue is that you don't have enough load. and the way you look up EJBs is odd.
To look up remote EJB, rather than the properties in a servlet. but the CORBA / IIOP URL in the JNDI resources of the server. (in the admin console)
When you load balance, with IIOP each lookup binds to one instance and only switches to another instance for failover.
essentially you don't have enough load on the system to trigger the other instances of the EJB. Perhaps reduce the pool size to one to simulate high load.

Related

Scoped vs Singleton ignite client node in .net web api

I am try planning to introduce Apache Ignite into existing old .net web api project to use it as key/value store for detecting duplicate requests sent to the load balanced api.
I would like to introduce minimum overhead to each request.
As I understand Client node is communicating to the server through TCP.
My current go to plan is to create a singleton object which will establish connection to the remote cache and register it in my DI container.
Is it ok to leave node running and TCP connection open or should make the ignite object scoped to start close on each request/response cycle?
Keep in open, as a singleton.
Ignite object is thread safe
It is expensive to create and connect to the cluster (in case of classic "Thick" client)
There is also a "Thin" client, which is very lightweight and can be created and disposed often. Note that thin client is also thread safe.
Also, you can try to use REST:
https://apacheignite.readme.io/docs/rest-api

How to share an ignite instance among jetty webapps

The docs state:
https://ignite.apache.org/releases/latest/javadoc/org/apache/ignite/startup/servlet/ServletStartup.html
Servlet-based startup may be used in any web container like Tomcat,
Jetty and etc. Depending on the way this startup is deployed the
Ignite instance can be accessed by either all web applications or by
only one. See web container class loading architecture:
But then points to a dead link regarding Jetty.
I'm using Jetty. How would this be done (sharing the ignite instance among all web applications)?
Link to Jetty classloading
Link to Ignite web configuration
The latter describes web session clustering but you don't have to enable that to use Ignite. I think these docs should cover your case.
To share Ignite instance between web apps, you will need:
Put Ignite libraries into server's main lib/ directory, and not under your web app directory
Instantiate Ignite using Jetty API, as per the documentation that you referenced
code:
Server service = new Server();
service.addListener("localhost:8090");
ServletHttpContext ctx = (ServletHttpContext)service.getContext("/");
ServletHolder servlet = ctx.addServlet("Ignite", "/IgniteStartup",
"org.apache.ignite.startup.servlet.ServletStartup");
servlet.setInitParameter("cfgFilePath", "config/default-config.xml");
servlet.setInitOrder(1);
servlet.start();
This assumes you are starting Jetty programmatically, i.e. with your own code. Your mileage may vary if you don't.

Deploy Java EE application without starting

I am using Apache Geronimo. I need a way to deploy an EAR application on an application server without starting the EAR module automatically.
When I deploy my EAR, it is automatically started. I need a way to specify, that it should only be deployed but not started.
Is there a way to do this?
In the past I've opened and closed gates to certain EJBs with the use of JMX.
The cool part:
100% Control your beans from outside using JConsole or your own JMX client.
The drawback:
Every bean instance has to be registered in the MBean Server which is not that cool as you are usually having multiple instances of the same bean.
The solution to this topic was having a #Singleton EJB working as a MBean/controller for all the instances of one EJB.

Lookup a Message Driven Bean via JNDI

If I create a MessageDriven bean - is it available to other components in my app via JNDI? If so, how can I find/specify the name to look it up by? I'm deploying to glassfish if that makes any difference?
Assigning a JNDI name for an MDB is not required by Java EE specification (chapter 21.2.3 of EJB 3.0):
At the minimum, the EJB container must provide a JNDI API name space to the enterprise bean
instances. The EJB container must make the name space available to an instance when the instance invokes the javax.naming.InitialContext default (no-arg) constructor.
The business interfaces of other enterprise beans
[...]
MDBs don't qualify, as they don't have a business interface. Besides, since wiring up an MDB in another EJB/MDB would have little sense (what's your use case, BTW?), is probably skipped in Glassfish.
I've seen that WebLogic, for example allows that in its proprietary deployment descriptor, but I've never used it.

WebSphere Application Server EJB Optimization

We are working on developing a Java EE based application. Our application is Java 1.5 compatible and will be deployed to WAS ND 6.1.0.21 with EBJ 3.0 and Web Services feature packs. The configuration is currently one cell with two clusters. Each cluster will have two nodes.
Our application, or our system, as I should rather say, comes in two or three parts.
Part 1: An ear deployed to one cluster that contains 3rd party vendor code combined with customization code. Their code is EJB 2.0 compliant and has a lot of Remote Home interfaces.
Part 2: An ear deployed to the same cluster as the first ear. This ear contains EBJ 3's that make calls into the EJB 2's supplied by the vendor and the custom code. These EJB 3's are used by the JSF UI also packaged with the EAR, and some of them are also exposed as web services (JAX-WS 2.0 with SOAP 1.2 compliance) for other clients.
Part 3: There may be other services that do not depend on our vendor/custom code app. These services will be EJB 3.0's and web services that are deployed to the other cluster.
Per a recommendation from some IBM staff on site here, communication between nodes in a cluster can be EJB RMI. But if we are going across clusters and/or other cells, then the communication should be web services.
That said, some of us are wondering about performance and optimizing communication for speed of our applications that will use our web services and EJB's. Right now most EJB's are exposed as remote. (and our vendor set theirs up that way, rather than also exposing local home interfaces). We are wondering if WAS does any optimizations between apps in the same node/cluster node space. If two apps are installed in the same area and they call each other via remote home interface, is WAS smart enough to make it a local home interface call?
Are their other optimization techniques? Should we consider them? Should we not? What are the costs/benefits? Here is the question from one of our team members as sent in their email:
The question is: Supposing we develop our EJBs as remote EJBs, where our UI controller code is talking to our EXT java services via EJB3...what are our options for performance optimization when both the EJB server and client are running in the same container?
As one point of reference, google has given me some oooooold websphere performance tuning documentation from 2000 that explains a tuning configuration you can set to enable Call By Reference for EJB communication when they're in the same application server JVM. It states the following:
Because EJBs are inherently location independent, they use a remote programming
model. Method parameters and return values are serialized over RMI-IIOP and returned
by value. This is the intrinsic RMI "Call By Value" model.
WebSphere provides the "No Local Copies" performance optimization for running EJBs
and clients (typically servlets) in the same application server JVM. The "No Local
Copies" option uses "Call By Reference" and does not create local proxies for called
objects when both the client and the remote object are in the same process. Depending
on your workload, this can result in a significant overhead savings.
Configure "No Local Copies" by adding the following two command line parameters to
the application server JVM:
* -Djavax.rmi.CORBA.UtilClass=com.ibm.CORBA.iiop.Util
* -Dcom.ibm.CORBA.iiop.noLocalCopies=true
CAUTION: The "No Local Copies" configuration option improves performance by
changing "Call By Value" to "Call By Reference" for clients and EJBs in the same JVM.
One side effect of this is that the Java object derived (non-primitive) method parameters
can actually be changed by the called enterprise bean. Consider Figure 16a:
Also, we will also be using Process Server 6.2 and WESB 6.2 as well in the future. Any ideas? recommendations?
Thanks
The only automatic optimization that can really be done for remote EJBs is if they are colocated (accessed from within the same JVM). In that case, the ORB will short-circuit some of the work that would otherwise be required if the request needed to go across the wire. There will still be some necessary ORB overhead including object serialization (unless you turn on noLocalCopies, with all the caveats it brings).
Alternatively, if you know that the UI controller is colocated, your method calls do not rely on parameter or return value copying, and your interface does not rely on the exception differences between local and remote views, then you could create and expose a local subinterface that will be much faster than remote access through the ORB.