服务间通信之Http框架
来源:互联网 发布:软件模块化设计原则 编辑:程序博客网 时间:2024/06/04 01:08
服务间通信之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,这个在下一篇文章中将要展开。
- 服务间通信之Http框架
- socket通信模拟http服务之python版
- Android框架之Camera(3)透过Camera服务看Binder进程间通信
- 网络通信之HTTP
- 《分布式服务框架原理与实践》读书笔记之第三章 通信框架
- angularjs之http服务
- 分布式游戏服务器框架sframe(二)—— 服务调度与服务间通信
- android开发框架(一)HTTP通信
- HTTP网络通信框架——Volley
- socket通信之http-server
- socket通信之http-server
- 软件通信之HTTP通信协议
- Android 之 网络http通信
- android http通信之httpclient
- Android之Http通信HttpConnection
- socket通信之http-server
- Unity网络通信之HTTP
- Android服务之Service(其二)关于AIDL进程间通信
- java编程题古典算法之兔子问题
- Android如何分析和研究Monkey Log文件
- 抓包参数tcp[13]详解
- linux内核虚拟化之路(一) cgroup机制
- debug断点调试
- 服务间通信之Http框架
- mysql修改字段的类型和相关属性
- struts1 工作流程
- 连接mysql数据库时Establishing SSL connection without server's identity verification is not recommended.
- 登录Hive
- mac升级python到3.6.2
- spring学习之aop关于xml文件配置和注解方式配置
- 深度学习算法评估指标
- FZU 2282 Wand (组合数学 错排应用)