How does Java Servlet and container actually works at each layer of Open Systems Interconnection model (OSI model)? Does the servlet container internally use operating system's native socket libraries via JNI? Is there even any other possibility for JVM to use networking?
The OSI model works great in theory as a guideline, but in practice is not always possible or easy to classify or separate the inner workings and protocols of a complex system in each of its layers. To better understand the protocol architecture of, for instance, a Java Servlet, it is much better to use the TCP/IP model since it is simpler than the OSI model.
Starting with the Link Layer, it has the task to translate an IP address to a MAC or physical address. The most famous protocol in this layer is the Ethernet. It mainly operates inside an Ethernet network card.
Next we have the Network and the Transport Layer, where we find the IP and TCP protocols, respectively. Both protocols are usually supported by the host operating system using a networking application programming interface (API). The most popular API is called sockets. In the case of Java, its objects have an underlying implementation that interfaces to native code (according to these sources: 1, 2, and 3).
And finally there's the Application layer, where we find the HTTP protocol. This protocol is implemented and supported by the application servers, such as Tomcat, JBoss and Glassfish.
Reference: This answer was based on the book TCP/IP Illustrated book, by Kevin R. Fall
Related
Consider this scenario: I have N>2 software components (microservices) that can communicate through two different communication protocols depending on how they are deployed. In other words, I have two deployment scenarios:
The components are to be deployed on the same machine. In this case I don't know if it makes sense to use HTTP to communicate these two components, if I think about performance. I understand that there are more efficient ways to communicate two processes on the same machine using java, such as sockets, RMI, RPC ...
The components are to be deployed on N different machines. In this case, it seems to me that it makes sense for me to use HTTP to communicate these components.
In short, what I want to do is to be able to configure the communication protocol depending on the way I perform the deployment: On a single machine, for example, use RMI, but when I deploy on two machines, use HTTP.
Does anyone know how I can do this using Spring Boot?
Many Thanks!
Fundamental building block of protocols like RMI or HTTP is socket communication. If you are not looking for the comfort of HTTP or RMI, and priority is performance, pure socket communication is your choice.
This will raise other concerns like, deployment difficulties. You should know IP address of both nodes in advance.
Another option, is to go for unix -domain socket for within server communication. For that you have to depend on JunixSocket.
If you want to go another route, check all inter process communication options.
EDIT
As you said in comment "It is simply no longer a question of two components but of many". In that scenario, each component should be a micro-service And should be capable to interact with each other. If that is the choice most scalable protocol are REST/RPC both are using HTTP protocol under the hood. REST is ideal solution for an API to be developed against a data source using CRUD operations. RPC is more lean towards action oriented API. You can find more details to identify the difference in between REST and RPC here.
How I understand this is...
if the components (producer and consumer) are deployed on the same host then use an optimized protocol and if on different hosts then use HTTP(s)
Firstly, there must be a serious driver to go down this route. I take it the driver here is performance. You would like to offer faster performance on local deployment and compartively compromised speeds on distributed deployments. BTW, given that we are in a distributed deployment world (or atleast where we are headed) HTTP will be what will survive. Custom protocols are discouraged.
Anyways... I would say your producer application should be in a self healing / discovery mode. On start-up (or periodically) it could check the health of the "optimized" end-point and decide whether it the optimized receiver is around. The receiver would need to stand behind a load-balancer. If the receiver is not up then go towards HTTP(S) and setup this instance accordingly at runtime.
For the consumer, it would need to keep both the gates (HTTP and optimized) open. It should be ready to handle requests from either channel.
In SpringBoot you can have a healthCheck implmented and switch the emitter on/off depending on the health of optimized end-point. If both end-points are unhealthy then surely the producer cannot emit anything. Apart from this the rest is just normal dependency-injection.
I'm looking at the Java API for MarkLogic, which I assume leverages the HTTP protocol for database connections. Is it possible to establish a connection over TCP? If not with the Java API, is it possible to interrogate the database by any means over TCP?
Our current architecture is based on a Microservice architecture concept, and includes a number of stages in any given process flow through the system, including Queueing, Message-brokering, etc. Given the number of steps, I'd like to optimise traffic-speed insofar as possible by leveraging TCP connections.
The Java API uses the REST Application services on MarkLogic which is fully HTTP 1.1 compliant and TCP/IP.
Not sure what else you are asking for.
For programs written in Java the Java API is the recommended API for most uses
http://developer.marklogic.com/products/java
You can also use the REST services directly, but the Java API adds a lot of Best Practice and exposes a higher level of abstraction to make coding simplier.
You can use the REST API from any application that can do HTTP
http://docs.marklogic.com/guide/rest-dev/intro
But its a bit more work as you have to construct your HTTP messages directly.
You can also create your own HTTP interface and access it through TCP/IP (HTTP) by making an HTTP App Server (written in XQuery).
Finally if you want very low level but effecient access, using Java or .NET you can use the XCC interface which is more tedious to use but provides a lower level feature for advanced users. This requires the Java or .NET library as the protocol is not documented.
https://developer.marklogic.com/products/xcc
What language are you going to be using and what kinds of operations ? That can help focus on which API is best for you.
-David Lee
HTTP is built on TCP. So by definition all HTTP connections are over TCP.
If you'd like a proprietary protocol instead of HTTP, one option is to forget the fact you learned that the Java API uses HTTP and imagine it uses TCP directly. :)
If you really want a proprietary protocol over TCP, you can use the XDBC protocol in combination with the XCC client. By default XDBC uses a wire protocol on TCP that isn't published.
what is the difference between socket programming, rmi and Servlets. When to use what?
The Socket APIs are the low-level (transport level) abstraction by which a Java application interacts with the network, and by extension with remote clients and services. Socket and related APIs support reliable byte stream and unreliable messaging services. They are typically used for TCP/IP and UDP/IP, though other networking protocol stacks can (at least in theory) be supported.
RMI is a framework and protocol family for implementing application-level networking between Java applications. It models network interactions as Java method calls made against objects that live in other applications. This model requires a mechanism (typically a name server) that allows one application to "publish" objects so that another application can refer to them. This (and the fact that RMI ports are typically blocked by default) means that there is a non-trivial amount of configuration effort in setting up RMI-based applications.
Servlets are a collection of APIs that are primarily designed for implementing the server side of HTTP communications; i.e. for building webservers in Java. They (or more accurately the web container in which they run) take care of the details of the HTTP protocol, so that the programmer (in theory) only needs to deal with "application" concerns.
In practice, the servlet developer and/or deployer has to deal with other things such as mapping URLs to servlets to objects, security and authentication. In addition, Servlets only deal with the server side of an HTTP interaction ... the client side must be handled by different APIs. (You could also argue that Servlets by themselves do not do enough, as evidenced by the proliferation of web application frameworks that are built on top of Servlets.)
In brief:
Sockets are for low-level network communication
RMI is for high-level Java-to-Java distributed computing
Servlets are for implementing websites and web services
Sockets -- Few simple calls which directly interface with TCP/IP. Very simple but you to implment your own buffer handling and deal with incomplete responses and timeouts in yourself. No authentication or security provided.
rmi -- handles all of the above, <personal opinion>its one of the worse APIs to have contaminated the java standards </personal opinion>, fairly simple to program, handles basic network errors, authentication and security issues. Difficult to configure and deploy.
Servlets -- lovely simple API, all network issues handled for you, security and authentication via plugins. No deployment issues, simple configuration.
Use sockets to implement a specific TCP/IP protocol, whether an existing standard or your own custom protocol. You have complete control over all aspects of network communication.
Servlets support request/reply semantics in the general sense, but it far more likely you will be using HTTPServlets which support, as expected, the HTTP request/reply semantics. For example, a web-server, or a RESTful HTTP based endpoint.
Use RMI for distributed Java Objects. RMI is itself implemented using Sockets (see above) and implements the Java Wire Protocol.
So my most basic question here is: how do you build TCP interfaces into your Java EE applications? Instead of interacting with a legacy EIS, I need to interact with a block of TCP/IP ports. Ideally, I'd like a message-driven bean to have it's onMessage method invoked by an incoming TCP request and also be able to respond back over the same connection.
JCA seems general enough to be capable of something like this within a Java EE environment. Would developing a custom connector be the appropriate technique for integrating inbound/outbound TCP interfaces in a Java enterprise ecosystem?
As far as what I've tried so far: we're currently utilizing a lifecycle module which starts by kicking off a number of TCP listeners; this invokes a message-driven bean which calls a business method, and it all returns over the same TCP stream. This is actually working alright, but the lifecycle support in my application server (Glassfish) feels like it has been added as an afterthought. So, JCA seems like a first-class solution to this sort of problem and it seems to enable us to communicate over TCP.
However, from the initial research we've conducted, it does seem like the connector architecture is 'targeted' towards legacy information systems, not generalized TCP communication. So, my question could be rendered: are people using custom JCA's to integrate TCP/IP into their Java EE applications -- or is there a better technique for accepting TCP connections from my EJBs?
MXBeans and JCA (MXBeans are easier, have implemented both) but basically you only need 2 things start/stop and possibly to rely on other MXBeans/JCA/JNDI to carry out your services w/ the AppServer generating the needed proxies for you.
Real application: hacked tomcat w/ the NIO acceptor that can trap connections on 80+443ports and still use the web-server normally.
Followed by full platform (incl. own (re)deployer) to manage sessions/messages and all the jazz.
It seems you already resolved your initial problem. It's nice, but to help people through, this is a nice sample on the matter: http://code.google.com/p/jca-sockets
I have to design a distributed application composed by one server (developed in Java) and one or more remote GUI clients (Swing application with windows).
As stated before the clients are Swing GUI application that can connect to the server in order to receive and send data.
The communication is bidirectional (Server <=> Clients).
Data sent over the network is mainly composed by my domain logic objects.
Two brief examples: a client calls the server in order to receive data to populate a table inside a window; the server calls client in order to send data to refresh a specific widget (like a button).
The amount of data transmitted between server and clients and the frequency of the network calls are not particularly high.
Which technology do you suggest me for the server-clients communication?
I've in mind one technology suitable for me but I would like to know your opinions.
Thanks a lot.
The first technology that came to my mind was RMI - suitable if you're communicating between java client and java server. But you may get difficulties if you want do switch the client technology to - say - a webinterface.
I would go with RMI but implement the whole architecture using Spring framework. This way it is independent of technology used and can be switched to other ways of communication (such as HTTP or other ) with almost no coding.
UPDATE: And Spring will allow you to have none of RMI specific code.
I believe sockets should do the trick. They are flexible and not especially hard to code/maintain. Most entry level programmer should also be able to maintain them. They are also fast and adapt to any kind of environment.
Unless, your server is going to be off-site or you expect to have firewall issues. In that case, web services are the way to go since your basic communication happens through port 80.
I would second msparer's suggestion of RMI, except I would just use EJB3 (which uses RMI as the communication protocol). EJB3 are very easy and even if you don't use the other feaures EJB gives you (e.g., security) you can still leverage Container Managed Transactions (CMT). It really does make development easy.
As for the server->client communication, you would probably want to use JMS. Again, using EJB3 this is pretty e3asy to do with annotations. The clients will subscribe to the message service and receive update notifications from the server.
And yes, I am currently working on an application that does this very thing. Unfortunately we are using EJB2.1. Still, it is my opinion that this is where EJBs really shine. Using EJBs in a web app is frequently overkill, but in a distributed client/server app they work very well.
You can try using ICE http://www.zeroc.com for establishing server-client connection.