服务间通信之Http框架

标签: 服务 通信 http | 发表时间:2017-08-03 04:15 | 作者:u012734441
出处:http://blog.csdn.net

服务间通信之Http框架


  • 1.服务间通讯调用

  • 2.jersey代理连接池

  • 3.综上

1.服务间通信调用


首先不提在微服务中,就是在我们使用spring cloud技术栈构建我们的服务中,如果我们需要调用其他的服务或者第三方的服务,一般的通信方式无非是http通信、rpc通信、异步消息通信等等,当然大多数服务一般都是以http接口的形式提供出来,那么可以用来调用该服务的方法可谓是多种多样,各式各样的http客户端,apache Httpclient、OKHttp、jersey-client、原生HttpURLConnection等等,大体以上几种我都用过,做了一些对比,可以看一下:

1.1 java原生HttpURLConnection


这个用的不多,在正式项目中几乎没有用过,写一些小的demo的时候偶尔用过,使用的原因更多是当时懒得再引入其他第三方的http框架了,用法如下:

  public static void sendPostJson() throws IOException {
        String path = "http://127.0.0.1:8080";
        JSONObject obj = new JSONObject();
        obj.put("id", "10001");
        obj.put("name", "xiaxuan");
        obj.put("sex", "M");
        String jsonStr = obj.toJSONString();
        byte[] data = jsonStr.getBytes();
        java.net.URL url = new java.net.URL(path);
        java.net.HttpURLConnection conn = (java.net.HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setRequestProperty("Connection", "keep-alive");
        conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
        conn.setRequestProperty("Content-Length", String.valueOf(data.length));
        OutputStream outStream = conn.getOutputStream();
        outStream.write(data);
        outStream.flush();
        outStream.close();
        if(conn.getResponseCode() == 200){
            BufferedReader in = new BufferedReader(new InputStreamReader((InputStream) conn.getInputStream(), "UTF-8"));
            String msg = in.readLine();
            System.out.println("msg: " + msg);
            in.close();
        }
        conn.disconnect();
    }

不多说,用法还是挺复杂的,简单的请求甚至需要数十行才能完成,并且不易于理解,当时写完调试了半天才通,挺后悔用原生的HttpURLConnection来进行当时功能的测试,感觉比我当时写的一个http-server还要麻烦,在正式的项目中一般不会用到原生http请求类。

1.2 apache HttpClient


apache common下的子项目,高效、功能丰富、易于使用,这个在我所在的公司中的所负责的项目中用的不多,找了一个,用法如下:

  public CloseableHttpResponse stream(String url) throws IOException {
        String fileId = url.substring(url.lastIndexOf("/"), url.length());
        url = this.bootConfig.getHttpFilesUri() + fileId;
        log.info("DefaultTransport files url: " + url);
        HttpGet get = new HttpGet(url);
        CloseableHttpResponse response = (CloseableHttpResponse)this.client.execute(get);
        return response;
    }

这个是内部请求一个下载图片使用的,get请求获取文件,使用比较简单,更多的使用方法还是请去官网看下吧:

http://hc.apache.org/httpclient-3.x/tutorial.html

1.3 OKhttp


这个是我在open server项目中使用的一款http框架,特性如下:

  • 支持http2.0,对一台机器的请求共享一个socket。

  • 采用连接池技术,可以有效的减少Http链接数量。

  • 无缝集成GZIP压缩技术。

  • 支持Response Cache,避免重复请求

  • 域名多IP支持。

以下是我在以前写的一个简单demo,项目中使用的是okhttp连接池,设置的参数较多,各种拦截器之类的,使用比较复杂,不再展示出来。

  OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
  Request request = new Request.Builder()
      .url(url)
      .build();

  Response response = client.newCall(request).execute();
  return response.body().string();
}

给我的感觉是确实是好用,相当易用的api,设置读取超时、写入超时、重试拦截器、长连接等等都很容易实现,在先前的文章
Spring boot使用ProxyFilter进行服务代理,这篇文章中使用的ProxyFilter里面原生使用的http连接池是使用的HttpClient的连接池,但是连接池中连接数太少,各种参数的配置不适合于我们系统的开发,替换成了OkHttp的连接池,后来我升级为Okhttp3之后,加上的重试拦截器等等。另外OkHttp的特性中还提到了另外一点,就是 OkHttp还处理了代理服务器问题和SSL握手失败问题,ssl握手失败问题是比较难定位和追踪的,在将公司内我所负责的模块升级为java8以后,因为https产生的问题就是多个,带来不少的麻烦。

1.4 jersey client


我所负责的另外一个项目中,使用的rest框架是jersey,调用其他服务使用的是jersey提供的jersey-client,用法如下:

      private static Client getClient () {
        return ClientBuilder.newClient().register(JacksonFeature.class);
    }

    public static EnterpriseRs openDomain (String url, EnterpriseDomain domain) {
        Client client = getClient();
        Response response = client.target(url).request().accept(MediaType.APPLICATION_JSON_TYPE)
                .buildPost(Entity.entity(domain, MediaType.APPLICATION_JSON_TYPE))
                .invoke();
       // String str = response.readEntity(String.class);
        EnterpriseEmailRs rs;
        String data = "";
        try {
            data = response.readEntity(String.class);
            rs = objectMapper.readValue(data.getBytes(), EnterpriseEmailRs.class);
        } catch (Exception e) {
            log.error("email exception {}", data);
            throw new ServiceException(SecurityError.ENTERPRISE_EMAIL_ERROR);
        }
        closeClient(client);
        return rs.getData();
    }

简单来说就是api使用简单,很舒服,但是需要和jersey一起来使用,没有单独拿出来进行http的请求。

2.jersey代理连接池


以上说了这么多的http框架,但是在使用的时候要实例化client或者从连接池里面拿出连接,进行各种配置,指定url,参数,接收数据类型等等,虽说可以讲所有的GET、POST、PUT方法的调用加上泛型修饰,但是未免有些臃肿,但也确实是有比较好的方法,我只写出接口,然后进行一定程度的配置后,调用这些接口就会去请求远程的服务,jersey确实是可以做到,在我所在公司,以在产品越来越大,进行模块拆分独立部署的时候,相互之间的内部调用的方法便变成了内网http请求,在这虽说更好的方法是使用rpc框架来进行模块之间的通信,但是对于我们的产品来说使用rest通信,然后进行一定程度的性能调优之后,还是可以接受的,因此便一直采用了这种通信方法。

jersey内置一个WebResourceFactory类,我们再使用的时候,注册webTarget,指定远程调用地址、编写的接口,然后使用的时候从resources中取出对应注册的接口,调用的时候,就是调用到远程服务,这个整个的配置十分复杂,要完全讲述下来需要搭一套完整的以jersey为rest框架的应用程序,基本上可以抽出来单独写一个系列了,这个有疑问的可以私信我单独讨论。

3. 综上


上述讲了多种http框架的使用,有的难用,有的易用,有的功能十分强大,支持各种特性、有的使用依赖于一个完整的rest框架,如jersey-client和jersey代理连接池等等,但是讲述以上内容并不是说对这几个http框架进行一个对比,而是要在spring cloud搭建的系统中使用一款http框架来进行服务间的调用,这一片是对我使用的http的框架的一个总结,下一篇将要讲述spring cloud中的feign,以一种十分优雅的形式调用远程服务,并且可以选择底层调用的http的框架是HttpClient还是OkHttp,这个在下一篇文章中将要展开。

作者:u012734441 发表于2017/8/3 7:59:46 原文链接
阅读:156 评论:0 查看评论

相关 [服务 通信 http] 推荐:

服务间通信之Http框架

- - CSDN博客推荐文章
2.jersey代理连接池. 1.1 java原生HttpURLConnection. 这个用的不多,在正式项目中几乎没有用过,写一些小的demo的时候偶尔用过,使用的原因更多是当时懒得再引入其他第三方的http框架了,用法如下:. 不多说,用法还是挺复杂的,简单的请求甚至需要数十行才能完成,并且不易于理解,当时写完调试了半天才通,挺后悔用原生的HttpURLConnection来进行当时功能的测试,感觉比我当时写的一个http-server还要麻烦,在正式的项目中一般不会用到原生http请求类.

http api服务网关

- - 互联网 - ITeye博客
http服务网关系统是一个对http服务进行治理的系统,通过该系统可以对调用方进行身份认证、服务授权许可(许可调用方使用某个http服务)、服务鉴权(是否能调用http服务)、请求流控、失败恢复、调用度量数据统计分析、服务依赖视图等. 整个系统架构如下图,分为三大部分:api网关、网关控制台、度量数据采集分析(这个未在图中体现).

实现了一个比nginx速度更快的HTTP服务器

- jyf1987 - 博客园-clowwindy的杂草牧场
在上次的FreeBSD和linux的nginx静态文件性能对比测试 后,我萌发了自己动手做一个简单的Web Server来搞清楚nginx高性能背后的原理的想法. 最后成功实现了一个基于epoll的简单的HTTP服务器,实现了200,404,400,304响应,并且性能比nginx高了一点点. 本文主要介绍这个HTTP服务器的原理和设计过程.

Comet:基于 HTTP 长连接的“服务器推”技术

- - k1121
转自:https://www.ibm.com/developerworks/cn/web/wa-lo-comet/. Ajax 技术资源中心,这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻. 任何 Ajax 的新信息都能在这里找到. 订阅 Ajax 相关文章和教程的 RSS 提要.

深入浅出:HTTPS 要比 HTTP 多用多少服务器资源?

- - 膘叔
话外页,这是一篇好文章,深入浅出的写出了很多东西,所以,值得一看,有时候,写文章就是这样,你写的越学术,别人越不鸟你,毕竟不是每个人的知识点都象你那么丰富. 所以一篇好的文章,能够很直白的表达出来才是最OK的. 说起来,当年白居易就是写诗给90岁的老太太听,她能听得懂,这就是好诗(这是老师当年说的,我没有认证过.

用nginx搭建基于rtmp或者http的flv、mp4流媒体服务器

- - 开源软件 - ITeye博客
这种方式要下载FLV视频文件到本地播放,一旦FLV视频文件下载完成,就不会消耗服务器的资源和带宽,但是拖动功能没有RTMP/RTMP流媒体方式强大,很多视频网站都是用HTTP方式实现的,如:YouTube,土豆,酷6等. 2、  RTMP/RTMP流媒体方式. 这种方式不用下载FLV视频文件到本地,可以实时的播放flv文件,可以任意拖拽播放进度条,但是比较消耗服务器的资源.

HTTP Headers 入门

- johnny - Time Machine
非常感谢 @ytzong 同学在twitter上推荐这篇文章,原文在此. 本文系统的对HTTP Headers进行了简明易懂的阐述,我仅稍作笔记. 什么是HTTP Headers. HTTP是“Hypertext Transfer Protocol”的所写,整个万维网都在使用这种协议,几乎你在浏览器里看到的大部分内容都是通过http协议来传输的,比如这篇文章.

HTTP基础

- - ITeye博客
HTTP的结构主要包括下面几个要点:. HTTP的版本主要有1.0,1.1 和更高版本.    1.1 及以上版本允许在一个TCP连接上传送多个HTTP协议,1.0能 .    1.1 及以上版本多个请求和响应可以重叠,1.0不能.    1.1 增加了很多的请求头和响应头.     一个请求行,若干小心头,以及实体内容,其中的一些消息头和实体内容是可选的,消息头和实体内容需要空行隔开.

HTTP Header 详解

- - 博客园_Ruby's Louvre
HTTP(HyperTextTransferProtocol)即超文本传输协议,目前网页传输的的通用协议. HTTP协议采用了请求/响应模型,浏览器或其他客户端发出请求,服务器给与响应. 就整个网络资源传输而言,包括message-header和message-body两部分. 首先传递message- header,即 http header消息.

HTTP负载测试

- - 博客 - 伯乐在线
英文原文: ON HTTP LOAD TESTING 来源: oschina. 有很多人在谈论HTTP服务器软件的性能测试,也许是因为现在有太多的服务器选择. 这很好,但是我看到有人很多基本相同的问题,使得测试结果的推论值得怀疑. 在日常工作中花费了很多时间在高性能代理缓存和源站性能测试方面之后,这里有我认为比较重要的一些方面来分享.