服务间通信之Http框架

标签: 服务 通信 http | 发表时间:2017-08-03 12: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网关、网关控制台、度量数据采集分析(这个未在图中体现).

美团 HTTP 服务治理实践

- - IT瘾-dev
2019 年 7 月 6 日,OpenResty 社区联合又拍云,举办 OpenResty × Open Talk 全国巡回沙龙·上海站,美团基础架构部技术专家张志桐在活动上做了《美团 HTTP 服务治理实践》的分享. OpenResty x Open Talk 全国巡回沙龙是由 OpenResty 社区、又拍云发起,邀请业内资深的 OpenResty 技术专家,分享 OpenResty 实战经验,增进 OpenResty 使用者的交流与学习,推动 OpenResty 开源项目的发展.

实现了一个比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消息.