I was trying to find out if there is any difference when I am calling a service through its local interface / remote interface in performance within the same JVM.
Based on this article:
http://www.onjava.com/pub/a/onjava/2004/11/03/localremote.html?page=last&x-showcontent=text
Local call should be a bit faster especially in cases for Collection of Objects.
Based on my testing I could not find a big difference between the two however maybe I was trying it with small amount of data.
But anyway I would like to know if it has any downfall to call a service through its remote interface when we are in the same JVM because in my project we are generating both local/remote interfaces however there are no real remote calls, the client and the service is within the same JVM and I am thinking about cleaning up the mess and removing the unnecessary generated remote views because people started to use both without reason.
Thanks!
implementation will vary between containers how remote interfaces perform, you cannot rely on it performing similar to local interfaces (though most containers will realize you're actually accessing a 'local' remote interface). There can be differences, like spawning a new thread for the remote call, passing values by reference (you can for example turn this on in jboss for in-vm remote calls), etc
serialization is always slow, it should be avoided whenever possible
basically just don't do it, absolutely no reason to use the remote interfaces unless you plan on splitting your application into multiple EARs
Related
when looking at gRPC, SOAP and REST neither of them use a naming service or registry. I was wondering why that is? what are the advantages to using a registry and what alternative do they use?
RMI registry is a way to expose several separate services on the same java (EE) server. This is roughly similar as for example deploying several gRPC services (created by implementing several different stubs from separate proto
service definitions) on the same gRPC server.
The difference is that in gRPC for example, the name of the service combined with proto file's package automatically becomes an ID for the given service instance (you cannot for example deploy 2 different implementations of the same gRPC service in 1 server). Similarly in case of REST, resource's path is its IDs within a given virtual server.
In RMI, OTOH, you can assign any name to an object during the deploy time. Hence you need an entity that resolves these names (usually via JNDI) into specific implementation objects.
Put simply, names/IDs of gRPC services or REST resources are implied by their definitions, while in RMI these things are decoupled.
This is useful in situations where you have several service instances implementing the same interface.
FYI: RMI is not the only example of such design: another one is for example CORBA.
RMI means remote method invocation. It is an OO-oriented approach and can only call methods on an object. The system doesn't have any way to call a bare function or a "class method" (a.k.a., static method). It is "OO all the way."
But that means you need a way to get the first object reference so that you can start calling methods and get other objects. That is solved by a registry.
gRPC and SOAP are both RPC-style message passing (just data; no objects) which can have something similar to a class method, by just choosing not to pass an object name. REST is functionally much more similar to RPC than something like RMI, and also passes around data.
REST has "references" to "objects" like https://example.com/orders/1234, but you can still call https://example.com/orders to get the list of orders. In an RMI system you'd need to get a reference to an instance of OrderManager and query it for the system's orders.
RMI is like DCOM, CORBA, Android Binder, and D-Bus. You might find my CloudNativeCon 2019 talk on the subject useful. (I start talking about what makes a reference special earlier in the talk with Unix Domain Socket.) It was a goal of the talk to help people understand how dramatically different RMI is from RPC. Modeling objects in the communication system changes the system substantially, introducing interfaces, type checking for casts, and garbage collection. In my mind, the registry is the least important of the changes, although it is the most visible.
For a few days, I am stuck at a (for me) quite challenging problem.
In my current project, we have a big SOA based architecture, our goal is to monitor and log all incoming requests, the invoked services, the invoked DAOs, and their result. For certain reasons we cant uses aspects, so our idea is to connect directly to the JavaVM and observe what's going on.
In our research, we found Byteman and Bytebuddy which both use the Java Machine Tool Interface to connect and inject code into the VM.
Looking closer at Byteman we discovered that we have to specify the Byteman-Operation for each operational class which in our case is simply impossible.
Would there be a better, more efficient way to log all incoming requests, the invoked services, the invoked DAOs, and their results? Should we write our own Agent which connects to the JMTI? What would you guys recommend?
I think the way to figure out a specific service method call can be overloaded. Wouldn't it be simplest and smarter to use APM?
I have five separate java processes; which are running as business logic modules. I would like to develop my process management application were i can start/ping/monitor/message child processes.
Also, it maybe sharing resources like cache etc with child processes over rest-ws or worst case rmi calls since requires additional overhead.
I was inclined toward webservice based api, which will keep sending information about business logic running within processes. The processes can be data churning, computation, notification process engines.
Any ideas?
One option is to use JMX, and publish one or more MBeans. Oracle has documentation on it. You can use the request information from the processes, or to send them signals to change their behavior.
The bare bones outline of what you would do is decide what methods you need to expose remotely in each of your child processes. Each of them should define an interface with those methods, then an implementation of that interface. Then those implementations need to be registered with the MBeanServer.
The advantage of this approach is that you will immediately get a bare-bones 'management application', because you can open JConsole against your processes and use the MBeans. If you then wish to create a separate application that will more cleanly present your data, you can do so at your leisure, without changing the child processes.
This approach does not really get you anyway to 'sharing a cache', but sharing a cache between processes (or machines) should really be a separate question (I think).
I am working on an application in Java on Google App Engine where we have a concept of RPC, but when should we ideally make use of RPC? The same functionality that I am doing with RPC could be implemented even without it. So in what scenario should ideally RPC be designed.....?
You typically use RPC (or similar) when you need to access a service that is external to the current application.
If you are simply trying to call a method that is part of this application (i.e. in this application's address space) then it is unnecessary ... and wasteful to use RPC.
... when should we ideally make use of RPC?
When you need it, and not when you don't need it.
The same functionality that I am doing with RPC could be implemented even without it.
If the same functionality can be implemented without RPC, then it sounds like you don't need it.
So in what scenario should ideally RPC be designed.....?
When it is needed (see above).
A more instructive answer would be scenarios where there are good reasons to implement different functions of a "system" in different programs running in different address spaces and (typically) on different machines. Good reasons might include such things as:
insulating one part of a system from another
implementing different parts of a system in different languages
interfacing with legacy systems
interfacing with subsystems provided by third party suppliers; e.g. databases
making use of computing resources of other machines
providing redundancy
and so on.
It sounds like you don't need RPC in your application.
RPC is used whenever you need to access data from resources on the server that are not available on the client. For example web services, databases, etc.
RPC is designed for request/response. i.e. you have a self contained request to a service and you expect a response (return value or a success/failure status)
You can use it anywhere you might use a method call except the object you are calling is not local to the current process.
I am in the process of refactoring 4 disparate software components that pretty much do the same thing into a single service (not a web service - necessarily or even likely). 3 are written in C++ while the last and most important is written in Java. The rest of the system is written in Java and therefore I will not be refactoring the C++ code and using JNI especially as the components currently written in C++ are scheduled to be replaced with Java components in a foreseeable future.
The component which is currently implemented in Java is actually a subcomponent of a larger component. Therefore when the larger/wrapping component wishes to use the subcomponent (being refactored into a service) it simply calls intra-process Java methods. If I refactor that subcomponent into a separate service the original wrapping component will lose the benefit it currently has of in process method invocation.
Should I then add a thread to the original/wrapping component to act as the service gateway or should I completely refactor out the code into a standalone service.
I hope that I have been sufficiently clear...
In general, there need not be a single instance of "service" and instances need not be invoked remotely. A strategy of co-deployment for performance or availability reasons is quite reasonable. You have a lot of gains simply by having a single implementation of the logic.
However if you already have a service infrastructure in place, where the service providers are perhaps managed in a particular way, it it probably desirable to be consistent.
So you need to understand the impact of separation, are those benefits of in-process invocation significant in this case? You also need to consider whether expsoing teh in-process service as a remotely callable service for other clients will adversely affect the performance of the existing system.
My gut feel: pull the code into a component capable of both local and remote invocation (in my world that could be done with a simple Stateless Session EJB) and deploy it twice. Once co-located with the original system. Once as a service. Sacrifice absolute consistency for minimal perturbation.