Announcement Announcement Module
Collapse
No announcement yet.
Performance problems with HTTPS Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Performance problems with HTTPS

    Has anyone used the Spring Android Rest Template over https?

    We've recently integrated this into our android application and are running into performance problems when we switch our REST urls to HTTPS.

    Everything works fine under HTTP. Response times from the server are around a second to invoke the REST template and deserialize our JSON object. However, when we switch over to HTTPS it's taking 10-20 seconds to get complete the request.

    Anyone else have this problem?

    Thanks,

    Charles

  • #2
    Re: Performance problems with HTTPS

    How are you connecting? Are you using RestTemplate.exchange with an HTTPS URI or some other mechanism?

    Comment


    • #3
      Slow:

      Code:
      template.getForObject("https://myserver/foo", Foo.class);
      Fast:

      Code:
      template.getForObject("http://myserver/foo", Foo.class);
      The difference is an order of magnitude (e.g. 500ms cf 5000-10000ms).
      Last edited by chudak; Mar 18th, 2011, 01:39 PM. Reason: fix method names

      Comment


      • #4
        Re: Performance problems with HTTPS

        Hmmmmm ....

        I seem to be getting a:

        Code:
        org.springframework.web.client.ResourceAccessException: I/O error: No peer certificate; nested exception is javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
        when I try something similar, however, I am using the exchange method because I want access to the HTTP headers rather than your getForObject:

        Code:
        ResponseEntity responseEntity = restTemplate.exchange("https://myserver/foo", 
        				    	                                     HttpMethod.GET, 
        					                                     new HttpEntity<String(headers), 
        					                                     null);

        Comment


        • #5
          The above url was just an example...that's not my actual server url.

          Comment


          • #6
            Re: Performance problems with HTTPS

            Yes, I know. I was actually using an internal Tomcat server to connect to. Like you, I was using "https://myserver/foo" as a stand-in for the real URL.

            Comment


            • #7
              Problem solved, kind of

              I think this has something to do with the hostname verification being done by the http components library. With my cert it appears very slow.

              Changing my template to use the default JSSE facilities made a HUGE difference (and I verified this earlier by trying to hit the same secured and insecured urls using URL.openConnection().

              Code:
              org.springframework.web.client.RestTemplate template = new org.springframework.web.client.RestTemplate();
              template.setRequestFactory(new org.springframework.http.client.SimpleClientHttpRequestFactory());

              Comment


              • #8
                Now I'm getting intermittent failures like the following:

                Code:
                Caused by: java.lang.IllegalArgumentException: No matching constant for [-1]
                at org.springframework.http.HttpStatus.valueOf(HttpStatus.java:369)
                at org.springframework.http.client.SimpleClientHttpResponse.getStatusCode(SimpleClientHttpResponse.java:47)
                at org.springframework.web.client.DefaultResponseErrorHandler.hasError(DefaultResponseErrorHandler.java:45)
                at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:442)
                at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:404)
                at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:202)
                The invocation will work then it will throw this error.

                Comment


                • #9
                  секреты игры &amp;

                  Интересно написано

                  Comment


                  • #10
                    @chudak and @dutchman_mn, I've opened a new JIRA for this issue. I'm assuming you were both using the M2 build. If not, please let me know. Thanks!

                    https://jira.springsource.org/browse/ANDROID-31

                    Comment


                    • #11
                      Yes I'm using M2.

                      FYI, I'm pretty sure that it's not a problem with the spring code base but with the commons httpcomponent library.

                      When I switched out the default client request factory the problem went away. However, I did find a problem with the SimpleHttpClientRequestFactory. When I used that one it seemed like every other request would fail in the emulator. But when I ran unit tests in a JVM it worked fine.

                      I ended up using the deprecated CommonsClientHttpRequestFactory and the problem went away.

                      FWIW, I think the problem is with the default host name verification algorithm in the http components library. When I did some profiling of my code in the emulator that appeared to be the bottleneck. For whatever reason, it works fine in the JVM but when you run it in the dalvik vm on an emulator (or on a device) it's super slow.

                      I didn't try switching out the hostname verifier but that was another option I was going to try.

                      You may want to rethink removing support for the http client, at least in the near future.

                      Comment


                      • #12
                        Ok, thanks for the additional information. Just to summarize, the SimpleClientHttpRequestFactory uses the java.net package. I've read, and your experience seems to be consistent, that some people have had issues with the Android implementation. I haven't personally seen this, but that is one reason we chose to default to the CommonsClientHttpRequestFactory in M1. The other being that SpringFramework already had a working implementation of the commons client.

                        As you know, the commons 3.x http client is not native to Android. SpringFramework didn't have a HttpComponents implementation in Spring Web at the time, so the HttpComponentsClientHttpRequestFactory in SpringAndroid is the first implementation we've had. Since the HttpComponents 4.0 client is also native to Android we decided to default to it in the M2 release and deprecate the commons 3.x client, to discourage pulling in the commons client jar. In fact, I've already removed it in the latest build snapshot.

                        Being native doesn't necessary mean it's better. The Android HttpComponents implementation is quite old, as this stackoverflow thread indicates. HttpComponents 4.1 is now available, so we'll probably want to have an implementation available in Spring Android, which would also require an external dependency.

                        http://stackoverflow.com/questions/5...ion-on-android

                        But you bring up a good point about being able to compare functionality of each of these. So in that light, it's probably worth leaving the commons client as an option, but not defaulting to it. Then if you elect, you can pull in the dependency and use it. Needless to say, your and the community's feedback and experiences are valuable in driving these decisions.

                        Comment

                        Working...
                        X