Should I use Traefik's GZIP compression or the server's? - spring

In general, and specifically in the case of Spring Boot Web (the original, not the reactive one, version 2.5.4), can I expect better performance/compression from the server's own native gzip compression option or from Traefik's middleware?
I'd assume the server's, but I'd rather not assume at all, and Traefik's page on the subject (here) doesn't seem to give any warning like "try to enable GZIP compression in your server's framework before enabling this middleware".

Related

Why is there no option to use SSLContext with GetTCP Processor in Apache Nifi?

Why is there no option to use SSLContext with GetTCP Processor(Processor that connects to a TCP Server) in Apache Nifi? it is confusing that there is the option for ListenTCP(the Processor acts as a Server allow clients to connect), and "PutTcp"(used for sending data back to a Server) but not for GetTCP.
File a JIRA ticket so it gets prioritized https://issues.apache.org/jira/projects/NIFI/issues/NIFI-10618?filter=addedrecently
"The GetTCP Processor does not seem to have received much attention since the original implementation. Supporting TLS through the SSL Context Service could be useful if you are interested in working on it. Taking a quick look at the code, however, implementing proper support for TLS looks like it would require significant refactoring of the design. GetTCP uses the Java NIO libraries, which is good in general, but makes it very difficult to support TLS. For this reason, adding support for TLS should also include refactoring the implementation approach to use Netty."

Does OkHttp support Link rel=preload header?

My team is working on making our REST API more 'hypermedia' by replacing compound documents with links to related resources. We'd obviously like to use HTTP/2 Server Push to make sure it's as fast as possible. However, because of our hosting provider, we are not able to run HTTP/2.
It seems like the second best option after Server Push would be to have the client prefetch related resources via Preload.
Does anyone know if OkHttp natively supports the Link rel=preload header?
It does not. But you should be able to enqueue these yourself by inspecting the headers.

Does an application developed on HTTP/1.x require modifications to run on HTTP/2?

In the HTTP/2 chapter in the High Performance Browser Networking book, there is a mention that
all existing applications can be delivered without modification.
Existing application using HTTP/1.1 use a request line, like POST /upload HTTP/1.1.
I think some code in our application should instead move the request line to a header frame. That means our application should consider the change from request line to header frame and deal with data frames as well.
Isn't that a modification?
This assumes your application is abstracted away from the raw HTTP implementation - as most applications are.
For example, let's assume you have created a Javascript web application (e.g. Angular), that talks through REST APIs to a web server (e.g. Apache), which proxies requests to a backend server (e.g. Node.js).
By adding HTTP/2 to the Apache Webserver your website and web application should benefit from HTTP/2 and be downloaded faster without any changes to your code. This despite the fact that your application (at both the front end Angular app and the back end Node.js server) likely uses a lot of HTTP semantics (e.g. Methods like GET and POST, headers... etc.). The web browser and web server should handle all the HTTP/2 stuff for you with no requirement to change your code or realise that you are using a different version of HTTP than what you originally write this app for as, fundamentally the concepts of HTTP have not changed even if the delivery method on the wire has.
Of course if you are writing at a lower level, and directly reading the bytes from the HTTP request then this may not be the case. But in most cases, unless you are writing a web server or browser, you will be going through a library and not looking at the direct request line and/or HTTP/2 frames.
Additionally, as the author of that book states above and below this quote, while changes will not be necessary in most cases to keep the application functioning, to get the most out of HTTP/2 may require changes to stop using HTTP/1.1 optimisations and learn new HTTP/2 optimisations.
To elaborate on BazzaDP's answer, from an application standpoint running on a web application framework, nothing changes. Those frameworks provide an abstraction of the underlying HTTP innards.
For example ASP.NET running on IIS provides a Request and Response object to the developer.
You can still use those objects' properties like Request.Headers or Response.Body, even though in HTTP/2 jargon those are called and transported different from HTTP/1.x.
The web server itself or the application framework running on top of it will handle the translation from network traffic to that object's properties and vice versa.

Why use AJAX when WebSockets is available?

I've been using WebSockets for a while now, I have chosen to create an Agile project management tool for my final year project at University utilizing Node server and WebSockets. I found using WebSockets provided a 624% increase in the number of requests per second my application could process.
However since starting the project I've read of security loopholes, and some browsers choosing to disable WebSockets by default..
This leads me to the question:
Why use AJAX when WebSockets seems to do such a great job of lowering latency and resource overhead, is there anything that AJAX does better than WebSockets?
WebSockets isn't intended to replace AJAX and is not strictly even a replacement for Comet/long-poll (although there are many cases where this makes sense).
The purpose of WebSockets is to provide a low-latency, bi-directional, full-duplex and long-running connection between a browser and server. WebSockets opens up new application domains to browser applications that were not really possible using HTTP and AJAX (interactive games, dynamic media streams, bridging to existing network protocols, etc).
However, there is certainly an overlap in purpose between WebSockets and AJAX/Comet. For example, when the browser wants to be notified of server events (i.e. push) then Comet techniques and WebSockets are certainly both viable options. If your application needs low-latency push events then this would be a factor in favor of WebSockets. On the other hand, if you need to co-exist with existing frameworks and deployed technologies (OAuth, RESTful APIs, proxies, load balancers) then this would be a factor in favor of Comet techniques (for now).
If you don't need the specific benefits that WebSockets provides, then it's probably a better idea to stick with existing techniques like AJAX and Comet because this allows you to re-use and integrate with a huge existing ecosystem of tools, technologies, security mechanisms, knowledge bases (i.e. far more people on stackoverflow know HTTP/Ajax/Comet than WebSockets), etc.
On the other hand, if you are creating a new application that just doesn't work well within the latency and connection constraints of HTTP/Ajax/Comet, then consider using WebSockets.
Also, some answers indicate that one of the downsides of WebSockets is limited/mixed server and browser support. Let me just diffuse that a bit. While iOS (iPhone, iPad) still supports the older protocol (Hixie) most WebSockets servers support both Hixie and the HyBi/IETF 6455 version. Most other platforms (if they don't already have built-in support) can get WebSockets support via web-socket-js (Flash based polyfill). This covers the vast majority of web users. Also, if you are using Node for the server backend, then consider using Socket.IO which includes web-socket-js as a fallback and if even that is not available (or disabled) then it will fall back to using whatever Comet technique is available for the given browser.
Update: iOS 6 now supports the current HyBi/IETF 6455 standard.
Fast forward to December 2017, Websockets are supported by (practically) every browser and their use is very common.
However, this does not mean that Websockets managed to replace AJAX, at least not completely, especially as HTTP/2 adaptation is on the rise.
The short answer is that AJAX is still great for most REST applications, even when using Websockets. But god is in the details, so...:
AJAX for polling?
The use of AJAX for polling (or long polling) is dying out (and it should be), but it still remains in use for two good reasons (mainly for smaller web apps):
For many developers, AJAX is easier to code, especially when it comes to coding and designing the backend.
With HTTP/2, the highest cost related to AJAX (the establishment of a new connection) was eliminated, allowing AJAX calls to be quite performant, especially for posting and uploading data.
However, Websocket push is far superior to AJAX (no need to re-authenticate or resend headers, no need for "no data" roundtrips, etc'). This was discussed a number of times.
AJAX for REST?
A better use for AJAX is REST API calls. This use simplifies the code base and prevents the Websocket connection from blocking (especially on medium sized data uploads).
There are a number of compelling reasons to prefer AJAX for REST API calls and data uploads:
The AJAX API was practically designed for REST API calls and it's a great fit.
REST calls and uploads using AJAX are significantly easier to code, both on the client and the backend.
As data payload increases, Websocket connections might get blocked unless message fragmentation / multiplexing logic is coded.
If an upload is performed in a single Websocket send call, it could block a Websocket stream until the upload had finished. This will reduce performance, especially on slower clients.
A common design uses small bidi messages transferred over Websockets while REST and data uploads (client to server) leverage AJAX's ease of use to prevent the Websocket from blocking.
However, on larger projects, the flexibility offered by Websockets and the balance between code complexity and resource management will tip the balance in favor of Websockets.
For example, Websocket based uploads could offer the ability to resume large uploads after a connection is dropped and re-established (remember that 5GB movie you wanted to upload?).
By coding upload fragmentation logic, it's easy to resume an interrupted upload (the hard part was coding the thing).
What about HTTP/2 push?
I should probably add that the HTTP/2 push feature doesn't (and probably can't) replace Websockets.
This had been discussed here before, but suffice to mention that a single HTTP/2 connection serves the whole browser (all the tabs/windows), so data being pushed by HTTP/2 doesn't know which tab/window it belongs to, eliminating it's capacity to replace Websocket's ability to push data directly to a specific browser tab / window.
While Websockets are great for small bi-directional data communication, AJAX still carried a number of advantages - especially when considering larger payloads (uploads etc').
And Security?
Well, generally, the more trust and control is offered to a programmer, the more powerful the tool... and the more security concerns that creep up.
AJAX by nature would have the upper hand, since it's security is built in to the browser's code (which is sometimes questionable, but it's still there).
On the other hand, AJAX calls are more susceptible to "man in the middle" attacks, while Websockets security issues are usually bugs in the application code that introduced a security flaw (usually backend authentication logic is where you'll find these).
Personally I don't find this to be that big of a difference, if anything I think Websockets are slightly better off, especially when you know what you're doing.
My Humble Opinion
IMHO, I would use Websockets for everything but REST API calls. Big data uploads I would fragment and send over Websockets when possible.
Polling, IMHO, should be outlawed, the cost in network traffic is horrid and Websocket push is easy enough to manage even for new developers.
In addition to issues with older browsers (including IE9, as WebSockets will be supported starting from IE10), there are still big problems with network intermediaries not yet supporting WebSockets, including transparent proxies, reverse proxies, and load balancers.
There are some mobile carriers that completely block the WebSocket traffic (that is, after the HTTP UPGRADE command).
With years passing, WebSockets will be more and more supported, but in the meantime you should always have an HTTP-based fall-back method for sending data to the browsers.
Most of the complaining I have read about websockets and security is from security vendors of web browser security and firewall security tools. The problem is they don't know how to do security analysis of websockets traffic, because once it has done the upgrade from HTTP to the websocket binary protocol, the packet content and its meaning is application specific (based on whatever you program). This is obviously a logistic nightmare for these companies whose livelihood is based on analyzing and classifying all your internet traffic. :)
WebSockets don't work in older web browsers, and the ones that do support it often have differing implementations. That's pretty much the only good reason why they aren't used all the time in place of AJAX.
I don't think we can do a a clear comparison of Websockets and HTTP as they're no rivals nor solve the same problems.
Websockets are a great choice for handling long-lived bidirectional data streaming in near real-time manner, whereas REST is great for occasional communications. Using websockets is a considerable investment, hence it is an overkill for occasional connections.
You may find that Websockets do better when high loads are present, HTTP is slightly faster in some cases because it can utilise caching. Comparing REST with Websockets is like comparing apples to oranges.
We should be checking which one provides better solution for our application, which one fits best in our use case wins.
An example of the differences between HTTP and Websockets in the form of a client-size lib that can handle Websocket endpoint like REST APIs and RESTful endpoints like Websockets on the client.
https://github.com/mikedeshazer/sockrest
Also, for those who are trying to consume a websocket API on client or vice versa the way they are used to. The libs/sockrest.js pretty much makes it clear the differences (or rather is supposed to).

JSON GZIP Design choice

I am working on a web application with dynamic content generated by a servlet running in a JBoss container and static content/load balancing being handled by Apache + mod_jk.
The client end uses jQuery to making AJAX requests to the servlet which processes them and in turn generates large JSON responses.
One thing I noticed is that the original author chose to manually compress the output stream in the servlet using something like below.
gzout = new GZIPOutputStream(response.getOutputStream());
Could this have been handled using mod_deflate on the Apache end? If you can do this, is it considered better practice, can you explain why or why not?
I believe it makes more sense to apply HTTP compression within Apache in your case.
If a server is properly configured to compress responses of this type (application/json, if the server-side code is setting the correct content-type), then it's being wastefully re-compressed after the manual compression anyway.
Also, what happens here if a client that doesn't support gzip makes a request? If you're compressing the response at the server level, it will automatically respond appropriately based on the request's accept-encoding header.
A little additional research shows a couple of good alternatives.
Issue:
There is a network channel that exists between Apache and Jboss. Without compression of any kind on the jboss end you'd have the same latency and bandwidth issues you have between Apache and your clients.
Solutions:
You can use mod_deflate on the Apache and accept uncompressed responses from jboss and compress before delivering to your clients. I could see this making some sense in certain network topologies(Proposed by Dave Ward).
You can apply a Java EE filter. This will filter responses compressing them before they exist the JBoss container. This has the benefit of compression at the JBoss level without a bunch of nasty GZIP related code in your business servlet.
JBoss with by default uses Tomcat as its Servlet engine. If you navigate to $JBOSS_HOME/deploy/jbossweb-tomcat55.sar you can edit the server.xml file to turn 'compression=on' attribute on the HTTP/1.1 connector. This will compress all responses outbound from the container.
The trade-off between 2 and 3 is compressing piece meal for different servlets or compressing all responses.

Resources