-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is there advisable to use okhttp instead netty? #8002
Comments
It depends on your use case and workload (e.g., modem-connected applications vs datacenter network). We'd generally recommend using Netty, as overall it's a more powerful transport and things (mostly, threading) can be turned very efficiently for high-performance network operations. I don't have numbers on my hand, @ejona86 may have more experience for it. I'd suggest trying it to see if throughput is a thing for your case. Note, there are many factors can impact the throughput and they may have different defaults in Netty and Okhttp (e.g., flow control window size), you may want to be aware of that when doing performance tuning. |
I don't think grpc-okhttp has support for OpenJSSE. gRPC handles the security for grpc-okhttp, so upstream support in okhttp doesn't buy you anything. |
Thank you @voidzcy @ejona86 for your reply. @ejona86 What I saw okhttp works out of the box with -XX:+UseOpenJSSE where as netty dont. I created a grpc client/server program where with netty I faced the issue as mentioned in #7907 But once I changed NettyChannelBuilder with OkHttpChannelBuilder thing started working for me and thats why I was under the impression okhttp has support for openjsse. Interms of okhttp library, I have configured my project with io.grpc:grpc-okhttp which internally uses mostly com.squareup.okhttp if I am not wrong and we are using java8. Below is the exact gradle dependencies I am using now. Do you see any issue with the configuration? or any clue why okhttp works with openjsse as u mentioned it dont have the support. Please let me know if you need further details. Thanks, Bapi |
Oh, because the problem is with netty-tcnative and OpenJSSE is replacing the normal classes, that's why OkHttp works. You can use Netty without netty-tcnative and that should work as well. If you exclude netty-tcnative-boringssl-static from you dependencies then it should fix the problem and use the JDK for security. But you can also explicitly request the JDK using NettyChannelBuilder: nettyChannelBuilder.sslContext(
GrpcSslContexts.configure(SslContextBuilder.forClient(), SslProvider.JDK).build()); That requires a semi-recent OpenJDK 8 build or newer, as ALPN was only recently backported to Java 8 from Java 11. |
Thanks @ejona86 I have excluded 'io.netty:netty-tcnative-boringssl-static:2.0.25.Final' as suggested and tried running the client with JDK security configured as given below. NettyChannelBuilder.forAddress(host, port).sslContext(GrpcSslContexts.configure(SslContextBuilder.forClient(), SslProvider.JDK).build()).build(); Java Version in Useopenjdk version "1.8.0_261" I am getting below exception
Could you please let me know if this java has alpn support, if not which version should I use. Do I have to add more libraries in my gradle scripts for alpn support? If needed I can create a sample github project and share, so that it will be useful for you as well to go through. Please let me know if that helps. Thanks Bapi |
It seems Netty is too old. Netty 4.1.49.Final added support ALPN via the backported Java 9 API ("Ensure we support ALPN when using java 8u251"). That means I'd suggest you using grpc version 1.32+ and the corresponding Netty version. Although I'm surprised you are getting as far as you are. I'd expect things to be more broken without direct OpenJSSE support (#7907). Normally that error message would be much more clear. The logic gRPC uses to pre-detect ALPN and produce a better error message is apparently finding the Java 9 ALPN API is available so it didn't give an error (I think; but for some reason I see the "pretty error"; see below). But Netty did its own checks and "Java 8 doesn't support ALPN" was a (reasonable-for-the-time) assumption in the Netty code, which then assumed it was expected to use Jetty ALPN boot which didn't work. If we need another iteration, then yeah, a reproduction may be in order. I tried to reproduce what you saw using the azul/zulu-openjdk:8 docker image and grpc-java 1.27.0, but tcnative was working even with
Excluding tcnative did let me reproduce openjsse/openjsse#22 but with Conscrypt:
Excluding Conscrypt gave the error I expected you to have gotten:
And no upgrading of gRPC/Netty fixes that because gRPC doesn't know that OpenJSSE is an option. The Java 9 API is sort of annoying to tell if it is supported, so even if the API itself is there, gRPC limits itself to just SunJSSE. |
I took a look at the grpc-okhttp ALPN detection code and while it also has some important limitations, it looks like it very well could detect the Java 9 ALPN API in your situation. So I would generally expect you'd need to use grpc-okhttp until #7907 is resolved. grpc-okhttp should mostly work fine, but it is client-only and each Channel will use 1-2 threads. For small to moderate scale it should work well enough. |
@ejona86 Thank you so much for your detailed explanations. I have tried with the same zulu version what is working for you but for me its the same exception as mentioned here JAVA in useopenjdk version "1.8.0_282" Gradle file
Its strange if the same worked for you only difference I can see the os, for me its windows and in your case its linux. And if I excluding io.netty:netty-tcnative-boringssl-static throw below Mar 26, 2021 12:42:23 PM io.grpc.netty.GrpcSslContexts defaultSslProvider Mar 26, 2021 12:42:23 PM io.grpc.netty.GrpcSslContexts defaultSslProvider Mar 26, 2021 12:42:23 PM io.grpc.netty.GrpcSslContexts defaultSslProvider Exception in thread "main" java.lang.IllegalStateException: Could not find TLS ALPN provider; no working netty-tcnative, Conscrypt, or Jetty NPN/ALPN available Couple of questions for your remark I would generally expect you'd need to use grpc-okhttp until #7907 is ### resolved
Thanks, Bapi |
@ejona86 Your input will be highly appreciable here :-) |
I disabled tcnative and I saw cast exceptions, but for Conscrypt. I can live with assuming the problem is the different platform; I can think of a few ways it could change behavior. I just sent out #8042 and I think it is pretty safe to include to the upcoming release next week (1.37). Let's see how all that goes. When I said "limitation" earlier I was speaking of the TLS ALPN logic specifically. That code will either work or not, and it looks like it'll work for you. grpc-okhttp should be able to handle lots of RPCs. There may be a few RPCs that fail if you do more than 2^31 RPCs on a connection, but that will be just a small blip of failures and it should recover fine. We know less about its performance characteristics if you are doing 100 MB messages or the like, simply because I'm not aware of anyone actually doing that in production with it. Looking at an older benchmark run I did (we care about "Before" because that PR ended up being reverted later), it does ½ the byte throughput as Netty but has the same latency for unary RPCs. It is multiple times faster than Netty for lots of small messages on a single stream (#6696), but that is a subtle conversation. |
I think this is all addressed now, as grpc-okhttp is fine to use outside of mobile but we want to be aware of deficiencies in grpc-netty so we can address them. With the release of v1.37.0 grpc-netty should be working now for Zulu when OpenJSSE is enabled. If I missed something, comment and this can be reopened. |
Hi,
I had recently raised one issue #7907 where it is mentioned the issue along with of usage of OpenJSSE and the same is raised in OpenJSSE community as openjsse/openjsse#22. I am not sure by when we can expect any fix for this, so we are trying one more alternative but need your advice on the same.
I can see okhttp library has by default openjsse support but it is advisable to use only for android clients. If I change netty channel to okhttp for our grpc communication which is not android though, will it have any impact in terms of performance or any other aspect? Will okhttp library will be able to handle high load transactions? So in one line is it advisable to use okhttp in place of netty for grpc communication?
Thanks, Bapi
The text was updated successfully, but these errors were encountered: