I have a web application that get deployed on a jboss (eap 6.2) domain with 2 nodes.
There are certain startup processes that need to be excecuted, however right now the processes run on both nodes. This is undesirable, I need the process to run only on 1 server (identified as primary).
Obviously this can be done by having a special system property set up 1 of the servers, howeever I am wondering if there is a standard Java EE way of designating a node as primary and then reading that configuration in the code?
There is no defined standard. Some application servers provide HA Singletons (https://developer.jboss.org/wiki/JBMHASingleton for JBoss 4.x and http://www.jboss.org/quickstarts/eap/cluster-ha-singleton/ for JBoss 7/Wildfly 8).
There are some approaches like using JGroups or persisting the state in some sort of database. You could also use a clustered JMS Topic. The first node broadcasts "I'm initializing" and others have to listen to it. That's not the best approach but it's within Java EE bounds.
Related
I have one master and two slave into domain modes, using and httpsession and distributable into web.xml but the session is not shaing into domains, Im access one node and work, but when access the other node the session is not sharing.
the configuration is the following
1 master
2 slaves(slave1, slave2)
1 server group (demo)
2 nodes (node11 server slave1, node21 server slave2 )
When access node 11 and make the login, and then chage to node21 the session is not persisted, and the result is null.
and try with another app for session but have the same issue
jboss eap is 7.2 and jdk is open jdk 1.8
I try using two different application of session sharing, and none of work.
Im try the same on on server on different ports and the session was shared
You need to add <distributable/> tag in your web.xml. You may need to enable session replication on your JBoss domain server as well. Refer https://developer.jboss.org/thread/277766 for more details.
You should also read JBoss EAP documentation on this Configuring high availbility
I'm not sure what you mean by master vs slave modes. This is not a concept on which EAP clustering relies.
Additionally, domain mode is about management, not about clustering. These are completely orthogonal concepts.
From a management perspective, servers within a given server-group share the same configuration. Generally, if the server-group is configured to use an "ha" profile (which defines a JGroups subsystem which is the starting point for cluster configuration), and multicast is allowed on your network, servers should form a cluster out-of-the-box.
If this is not happening, look to your server logs to figure out what is happening, and to the docs for configuring JGroups discovery w/out multicast.
I'm working with microservices in Java Spring MVC. With Kubernetes, the pods containing this microservice application logic can scale/replicate based on incoming load. In few words, there can be 2 or more copies of my application running.
I require to have a specific identifier mechanism which describes the specific pod replica / container containing the application. I was thinking to generate a random number as a descriptor at runtime and store it as an identifier to the container. But I was wondering if there is a better way, considering that I am working with Spring, TomCat and Kubernetes, I would expect that some of this tech stack can do something like this for me?
Kubernetes can do this. Each Pod will have a unique name that you can access as the hostname or through an environment variable. If you use a standard Deployment resource though this can change if the Pod dies and is recreated. It sounds to me like you want a StatefulSet, in which Pods are assigned unique ordinal indexes and retain these when recreated - https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-identity
I'm currently developing a small EJB application running on IBM Websphere Application Server 7 (Java EE 5). The app mainly consists of one MDB listening for incoming MQ messages which are transformed and stored in a DB. Currently I'm using a lot of Singleton/Factories to share configurations, mappings, datasource lookups etc. But this actually leads to some very hard to test code. The solution might be using a (simple) DI framework like guice/spring to inject the different instances. The question is: Where to place the initialization/ setup code? Where is the main entry point of the application? How can I inject instances into the MDBs?
it might be worth looking at backing off from using Guice, and trying to work with the injection mechanisms already available with Java EE 5.
Regarding finding a suitable "startup point", unfortunately the EJB specification does not define a way where you can have a bean run at startup. However, the web profile of the EE spec does have one -- you can add a WAR to your application, and set a servlet listener component:
http://java.sun.com/javaee/5/docs/api/javax/servlet/ServletContextListener.html
You can set this to start whenever the application is loaded and started by the container (WebSphere). Watch out for classloader issues though.
Using Spring, you can do it via EJB3 interceptors, see http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ejb.html#ejb-implementation-ejb3
Useful info on caveats are in the javadoc, make sure you read it: http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/ejb/interceptor/SpringBeanAutowiringInterceptor.html
Is there a way to find all nodes belonging to the cluster of the web-application? I know on JBoss i can use HAServiceMBeanSupport to get information about all nodes(hostname, IP-adress), but how can I achieve something similar on Tomcat, WebSpere, Glassfish, Oracle AS, Jetty, WebLogic?
(Best would be an interface which works for all of them)
There is no standard drop-in solution for what you are asking for.
Technically it can be achieved in many ways - both within java ecosystem and outside e.g. Jgroups cluster forming, Zookeeper or simple Redis or other K/V server where each server instance would register upon startup and subscribe for changes in the cluster group.
The support and required effort will vary though. The general approach would be to use some startup hook e.g. Servlet container initialization or EJB #Startup #Singleton to contact the topology discovery service(your redis server for example), provide the info about your instance and query info about the other instances already active. If you need leader election, you can use many algorithms, e.g. first come-first serve basis, or based on voting. Then you need to subscribe and actively listen for changes in topology, and possibly provide some kind of health metric - e.g. periodically let others know, that your instance is still active
On a general note, can you elaborate why would your app need to have the knowledge about other instances of the same type? Do you need Master election or HA cluster-wide singleton functionality? The best practice for building stable scalable solutions is to keep the app stateless and unaware of the scaling details.
Functions, that need to be only executed in sequence or on a single node at the time, could be extracted into a dedicated service e.g. batch job service, scheduler service etc.
Most JEE server vendors offer some custom solution for this e.g. JBoss HASingleton service, or HA singleton deployment(app will always run only on a single instance in the cluster) which also takes care of failover.
As far as I know, it depends of the capabilities of your Applicationserver.
There is no "standardway" to do this.
You can try the following:
The class ServletContextListener has two methods. You can calculate the hostname and the IP-Adress(es) within the create method, and delete the node in the destroy method.
This way has problems during a VM-crash the destroy-method will not be called, for instance.
EDIT:
Does your software need a Database? If so, all clusternodes have to use the same database instance. If your app is deployed without a cluster it uses a "private" database. You need a shared DB:
Table: NODES
HOST | IP
as1.cluster | < ip >
as2.cluster | < ip2 >
If only onne line inserted to that DB, there is no cluster.
But this table may be corrupted, if a node crashes and does not remove its entry from this Table.
I need some direction with JMX and Java EE.
I am aware (after few weeks of research) that the JMX specification is missing as far as deployment is concerned. There are few vendor specific implementations for what I am looking for but none are cross vendor. I would like to automate the deployment of MBeans and registration with the Server. I need the server to load and register my MBeand when the application is deployed and remove when the application is un-deployed.
I develop with:
NetBean 6.7.1, GlassFish 2.1, Java EE 5, EJB 3
More specific, I need a way to manage timer service runs. My application need to run different archiving agents and batch reporting. I was hoping the JMX will give me remote access to create and manage the timer services and enable the user to create his own schedule. If the JMX is auto registered on application deployment the user can immediately connect and manage the schedule.
On the other hand, how can an EJB connect/access an MBean?
Many thanks in advance.
Gadi.
I investigated JMX and EJB in Glassfish few years ago, so I don't remember all the details. But this might still help.
Glassfish-specific JMX. Glassfish has AMX and custom MBean can be deployed. AFAIK, such beans are meant to monitor the server itself, not to interact closely with a specific application. Such bean can be made persistent, and Glassfish will store their value somewhere across restart. Maybe have a look.
Registration and lookup. You can register MBean anytime from within an application using the MBeanPlatform, or MBeanServer. See this link, I don't remember exactly. You can also lookup other JMX bean and invoke operations on them. The names for the lookup are a bit crazy though. You can register the MBean when the app. starts from within a ServletContextListener.
Classloaders and deployment. The MBeans and the EJB instances are in distinct Classloader. I think you will need to place the .jar with the MBean implementation in the Glassfish deployment directory structure or add it the list of .jar in the classpath via the admin console. You can relatively easily manage to register a bean from within an EJB module, but a bean can not access a EJB easily, at least from my experience.
I managed to use plain JMX to expose statistics from my EJB application, and that worked relatively well. But I don't know if it's adequate to have something more interactive, as in your case where you want to have the EJB change their behavior depending the timer configured with JMX. I fear you will have troubles with this approach.
Hope it helps, despite the vagueness of what I remember.