Servlet 4.0, JAX-RS 2.1, and HTTP/2 Multiplexing - java

I am reading https://www.mnot.net/blog/2019/10/13/h2_api_multiplexing and wondering what it means for our HTTP API implemented in JAX-RS 2.1; especially this excerpt:
Your server implementation will also need to be carefully considered to exploit this kind of request pattern
I've read that Java 9 introduced client APIs for HTTP/2, and that Servlet 4.0 introduced support for HTTP/2 server features like Server Push.
What I'm wondering is if the JDK (or below) are automatically handling the initiation of the HTTP/2 connection and/or the multiplexing aspect of the protocol, or is there something I need to do in our server config to ensure HTTP/2 (and especially the multiplexing feature) is properly supported. Or maybe its server-implementation-specific?

Related

Migrate Netty Websocket to Jetty Websocket

My application uses a custom binary protocol which is implemented with Netty. Recently I changed it to use Netty's websocket implementation. It works quite well.
My application also has a Jetty web server included and it offers websockets, too. Now I want to reduce the opened ports my server needs and handle all http traffic with one port.
I see three options:
Use either Netty or Jetty to proxy the traffic which belongs to the other implementation.
Reimplement the custom protocol on Jetty without the use of Netty's channels and piplines.
Create a custom implementation of Netty's channels that sends and receives it's data not over a socket but the methods Jetty's WebSocketListener offers.
Since Netty provides such a good api for writing binary protocols and a proxy sounds like extra problems to me I tend using the third approach. It shouldn't be too difficult to implement even though I don't know how to do it, yet.
Any thoughts what would be the best option and how I should implement it?

Can we use Apache to deliver HTTP/2 connection for a java application server?

Here is the basic architecture I currently use to deliver access to web application (AngularJS on the front-end - JEE-JAX-RS for the back-end REST API):
Client -> Apache -> Application server (Java container - ex. tomcat)
The client browser connect to the application through HTTPS (handled by Apache) and Apache forwards the connection to the Java container (I'm using Oracle Weblogic).
Everything works fine. But now I'd like to use HTTP/2.
Apparently, HTTP/2 will be available only in JEE8 (Servlet v4) which means it will not be available in solution like Weblogic before a loooong time.
Actually I have two questions :
Can I just activate Apache mod_http2 and configure my front-end
(AngularJS) to communicate in HTTP/2 or is it also necessary for my
application server to be able to handle HTTP/2 ?
If Apache receive connection in HTTP/2 and forward it to the Java
container through HTTP/1.1 or AJP will I still benefit from all the HTTP/2 advantages, even if part of the connection is not in HTTP/2 ?
Apache (and Nginx) do not currently have the capability to work in reserve-proxy mode and communicate to the backend using HTTP/2.
When you have such "mixed" communication (browser to Apache in HTTP/2 and Apache to backend in HTTP/1.1 or AJP) you are losing a number of optimizations that HTTP/2 brings, in particular multiplexing and HTTP/2 push, not to mention the overhead due to translating the request from HTTP/2 to HTTP/1.1 and viceversa.
HTTP/2 is already available in the Java world: Jetty (I am the Jetty HTTP/2 lead), Undertow and Netty already provide transparent HTTP/2 support so that you just deploy your JEE application, enable HTTP/2 and it's done.
Because of these limitations of Apache and Nginx, we currently recommend to use HAProxy in front of Jetty (as explained in details here).
This configuration will give you the maximum benefit for HTTP/2: fast TLS offloading performed by HAProxy, powerful load balancing, very efficient communication with the backend (no translation to HTTP/1.1), with HTTP/2 everywhere and therefore all its benefits.
Jetty also offers an automatic HTTP/2 push mechanism, which is not available, to my knowledge, in Apache or Nginx.
Specifically for your questions:
You can activate mod_http2 so that browser and Apache will communicate via HTTP/2, but you may lose HTTP/2 Push. Communication with the backend will use HTTP/1.1, however. This will work but it's not an optimal HTTP/2 deployment.
You will not benefit of any HTTP/2 advantage in the communication between the client and the backend if part of the communication is not in HTTP/2.
Yes, you can activate mod_http2 in httpd.conf file in Apache24/conf folder. You also need to enable the following modules:
1. mod_log_config
2. mod_setenvif
3. mod_ssl
4. socache_shmcb_module
You have to include the httpd-ssl.conf file in your httpd.conf file by uncommenting the line -- include /extra/httpd-ssl.conf
Include the certificate and key in the conf folder and set their paths in the https-ssl.conf file
The above steps will enable HTTP/2 in Apache 2.4
You can enable HTTP/2.0 for your Java Application hosted on Tomcat by installing Tomcat-9. Tomcat-9 supports HTTP/2.0 and server push services.
You can redirect your Requests from Apache 2.4 to Tomcat 9 using the instructions in the below link
https://www3.ntu.edu.sg/home/ehchua/programming/howto/ApachePlusTomcat_HowTo.html
Using these steps you can enable HTTP/2.0 to work between client browser, Apache and your Java Application. You will get the full benefits of HTTP/2.0 in this way.
I have already implemented all the above steps in my Project and getting full rewards of high performance in communication.
If you have any doubts you can leave your comments here.
HTTP/2 is also available in Tomcat 8.5

Jetty WebSocket api vs the standard JSR 356 API

Jetty 9 supports both it's own Jetty Websocket API as well as the standard JSR 356 API, for what I assume are historical reasons (Jetty's API precedes the final JSR 356).
I've looked over the basic documentation of both APIs, as well as some examples. Both APIs seem fairly complete and rather similar. However, I need to choose one over the other for a new project I'm writing, and I'd like to avoid using an API that might be deprecated in the future or might turn out to be less feature-rich.
So are there any important differences between the two except for the obvious fact that one is standardized?
Implementor of both on Jetty here :)
The Jetty WebSocket API came first, and the JSR-356 API is built on top of it.
The JSR-356 API does a few things that the Jetty WebSocket API does not, such as
Decoder's for automatic Bin/Text to Object conversion
Encoder's for automatic Object to Bin/Text conversion
Path Param handling (aka automatic URI Template to method param mapping)
However, the Jetty WebSocket API can do things the JSR-356 API cannot.
WebSocketCreator logic for arbitrary creation of the WebSocket endpoint, with access to the HttpServletRequest
Better control of timeouts
Finer buffer / memory configurations
You can manage WebSocket Extensions
Supports Reg-ex based Path mappings for endpoints
Access to raw Frame events
WebSocket client supports HTTP proxies (JSR-356 standalone client has no configuration options for proxies)
WebSocket client supports better connect logic with timeouts
WebSocket client supports SSL/TLS (JSR-356 standalone client has no configuration options for SSL/TLS)
Access to the both InetAddress endpoint information from the active WebSocket Session object
Access to UpgradeRequest from active WebSocket Session object
Better support for stateless endpoints
Read events support suspend/resume logic to allow application some basic tcp backpressure / flow control
Filter based or Servlet based configuration (the JSR-356 approach requires upgrade to occur before all other servlet and filter processing)
Hope this helps, if you want more details, please use the jetty-users mailing list, as this sort of question is really inappropriate for stackoverflow.

MarkLogic TCP Connection

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.

Non-blocking Web Server for java

I was reading about "Tornado Web Server".
It says that it is non-blocking web server.
Is there any non-blocking server for java web app ?
You're thus looking for a Java servletcontainer/applicationserver which supports NIO (Non Blocking IO).
Pretty much all of them supports NIO: Apache Tomcat, JBoss AS, Oracle Glassfish, etcetera. On some of them (e.g. Apache Tomcat), you've to make some configuration changes first (see also its HTTP connector documentation with regard to NIO). Glassfish uses under the covers Grizzly as NIO implementation of the HTTP connector.
As to which one to choose, that depends on what parts provided by the huge Java EE 6 API you'd like to utilize. If it's just JSP/Servlet, then Tomcat suffices. If you need a bit more than just JSP/Servlet, the Glassfish Web Profile may suffice. If you'd like to utilize the entire Java EE 6 API, then go ahead with JBoss AS or Glassfish Full Platform.
Also there is a non-blocking library in java called Netty and you can use Netty to write asyn network servers like web servers.
Non-blocking sockets have been available in Java in the java.nio pacakges since Java 1.4.
The Grizzly server is a servlet container based exclusively on NIO. Most established Java webservers are older than the NIO feature and have added support for it at some point.
Besides servers that BalusC listed, there is also Grizzly.
Here is a nice description of it's non-blocking operation.

Categories

Resources