场景:

认证服务器需要有个 http client 把前端发来的请求转发到 backend service, 然后把 backend service 的结果再返回给前端,服务器本身只做认证功能。

遇到的问题:

  • 长连接以保证高性能。RestTemplate 本身也是一个 wrapper 其底层默认是 SimpleClientHttpRequestFactory ,如果要保证长连接, HttpComponentsClientHttpRequestFactory 是个更好的选择,它不仅可以控制能够建立的连接数还能细粒度的控制到某个 server 的连接数,非常方便。在默认情况下,RestTemplate 到某个 server 的最大连接数只有 2, 一般需要调的更高些,最好等于 server 的 CPU 个数

  • access_token 不应传到 backend service. backend service 之间通信不需要 token,因为到这些服务的请求都是已经认证过的,是可信赖的用户发出的请求。因此转发请求时要把 parameter 从 request url 中删掉。删除 parameter 说难不难,说简单其实还有点麻烦,网上有一个 UrlEncodedQueryString 可以参考下,它封装了很多函数,其中就包括从url 中摘掉指定 header

  • 请求的 HttpMethod 问题。 HttpMethod 有很多种,http client 不应该对每种 Http method 都单独处理,所以应选用 RestTemplate 的 exchange 方法。exchange 方法要求给出 RequestBody 参数,而对于 Get 请求,这部分往往为空,所以我们要在 controller 中声明 @RequestBody(required = false) String body

  • exchange 的返回值和 controller 的返回值。Restful API 一般都是返回 json 的,所以最简单的是 exchange 和 controller 直接返回 String,但是返回 String 会有很多问题: 首先是如果某些 API 返回的是图片,那么这个 client 就傻掉了,需要为图片接口专门写 API,此外如果 backend service 返回的是 Gzip,那么此 client 必须对 gzip 先解压缩再返回请求者,如果不解压缩的话,相当于对着 gzip 数据做了到 String 类型的强制转换,使得请求者拿到的数据无法解析,所以最好的返回值是 byte[]。对于那种比较大的 json 返回值,省去了对 String 的类型转换后还能带来很大的性能提升

  • 关于返回值是 byte[] 还是 ResponseEntity<byte[]> 的问题。我觉得还是 ResponseEntity<byte[]> 好些,因为它就是 backend service 的结果。如果返回 byte[] 的话,还要对 HttpServletResponse 的 Header 进行修改,设置 Content-type, Content-encoding 等等。

下面是我的用法

    @PostConstruct
public void setProperties() {
clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(
HttpClientBuilder.create()
.disableContentCompression()
.setMaxConnPerRoute(restTemplateConfig.getMaxConnPerRoute())
.setMaxConnTotal(restTemplateConfig.getMaxConn()).build());
restTemplate = new RestTemplate(clientHttpRequestFactory);
} public RestTemplate getInstance() {
return new RestTemplate(new HttpComponentsClientHttpRequestFactory(HttpClientBuilder.create().build()));
} public ResponseEntity<byte[]> mirrorRest(@RequestBody(required = false) String body, HttpMethod method,
HttpServletRequest request, HttpServletResponse response, URI uri) throws URISyntaxException { HttpEntity entities = new HttpEntity(body, extractHeaders(request)); //delete accesstoken before mirror to backend server
UrlEncodedQueryString queryString = UrlEncodedQueryString.parse(uri);
queryString.remove("access_token");
uri = queryString.apply(uri); ResponseEntity<byte[]> responseEntity = restTemplate.exchange(uri, method, entities, byte[].class); return responseEntity;
}

需要改进的地方

  • HttpComponentsClientHttpRequestFactory 的配置粒度不够细,可以配合 RequestConfig 确定某一个 service 需要多少连接数。

  • RestTemplate 有异步版本 asyncRestTemplate, 可以考虑用它结合 netty 进一步提升程序性能,但是目前来讲已经够好了

RestTemplate 使用总结的更多相关文章

  1. HttpClient的替代者 - RestTemplate

    需要的包 ,除了Spring的基础包外还用到json的包,这里的数据传输使用json格式 客户端和服务端都用到一下的包 <!-- Spring --> <dependency> ...

  2. RestTemplate发送请求并携带header信息

    1.使用restTemplate的postForObject方法 注:目前没有发现发送携带header信息的getForObject方法. HttpHeaders headers = new Http ...

  3. 【Spring-web】RestTemplate源码学习——梳理内部实现过程

    2016-12-28 by 安静的下雪天  http://www.cnblogs.com/quiet-snowy-day/p/6228198.html  提示:使用手机浏览时请注意,图多费流量. 本篇 ...

  4. 【Spring-web】RestTemplate源码学习

     2016-12-22   by 安静的下雪天  http://www.cnblogs.com/quiet-snowy-day/p/6210288.html 前言 在Web开发工作中,有一部分开发任务 ...

  5. RestTemplate配置

    什么是RestTemplate? RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效 ...

  6. 使用RestTemplate发送post请求

    最近使用RestTemplate发送post请求,遇到了很多问题,如转换httpMessage失败,中文乱码等,调了好久才找到下面较为简便的方法: RestTemplate restTemplate ...

  7. Spring Boot+Cloud RestTemplate 调用IP或域名

    在SpringBoot+Cloud的项目中,我们使用了自动配置的OAuth2RestTemplate,RestTemplate,但是在使用这些restTemplate的时候,url必须是服务的名称,如 ...

  8. Spring RestTemplate: 比httpClient更优雅的Restful URL访问, java HttpPost with header

    { "Author": "tomcat and jerry", "url":"http://www.cnblogs.com/tom ...

  9. RestTemplate实践

    什么是RestTemplate? RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效 ...

  10. RestTemplate 请求url

    1.get 请求 RestTemplate restTemplate = new RestTemplate(); String url = ""; JSONObject resul ...

随机推荐

  1. MongoDB安装及shell简介

    MongoDB安装 MongoDB具有跨平台的优良特性,提供了对主流的操作系统支持,我们可以根据自己使用的操作系统,选择下载对应的安装包. 图 1. MongoDB支持各个版本的操作系统 MongoD ...

  2. 转:DataSet、DataTable、DataRow、DataColumn区别及使用实例

    DataSet 表示数据在内存中的缓存. 属性 Tables  获取包含在 DataSet 中的表的集合. ds.Tables["sjxx"] DataTable 表示内存中数据的 ...

  3. tar-usage

    tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的 ...

  4. Html5 学习系列(六)Html5本地存储和本地数据库

    一个网站如何能在客户的浏览器存储更多的数据呢? 在Html4的时代在浏览器端存储点网站个性化的数据,尤其是用户浏览器的痕迹,用户的相关数据等一般只能存储在Cookie中,但是大多是浏览器对于Cooki ...

  5. MySQL group_concat 1024 大小

    1. GROUP_CONCAT有个最大长度的限制,超过最大长度就会被截断掉,你可以通过下面的语句获得: SELECT @@global.group_concat_max_len; show varia ...

  6. 优化TableView性能

    优化tableView性能(针对滑动时出现卡的现象) (2013-08-02 11:18:15) 转载▼ 标签: ios tableview it 分类: 技术文档 在iOS应用中,UITableVi ...

  7. DOM基本概念和操作

    1.基本概念 DOM是文档对象模型(TEXT),对象是指文档中的每一个元素. 2.Window对象操作 打开方式: _blank  在新窗口还是自身窗口. Window.open 也有返回值,返回值为 ...

  8. es6学习笔记5--promise

    所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise是一个对象,从它可以获取异步操作的消息.Promise提供统一的API, ...

  9. bzoj 1191: [HNOI2006]超级英雄Hero

    1191: [HNOI2006]超级英雄Hero Time Limit: 10 Sec  Memory Limit: 162 MB 二分图匹配... Description 现在电视台有一种节目叫做超 ...

  10. 大家一起写mvc(二)

    上一篇已经看了,我想大家都明白了mvc的原理,今天我们来说一下要写自己mvc框架必须要会的技术. mvc的目录是这样的 src目录是我们核心的mvc代码.这个代码明天讲,今天主要讲的代码都在test目 ...