场景:

认证服务器需要有个 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. C#结合LumiSoft.Net.dll读取Outlook邮件(.eml格式邮件)

    如果直接从Outlook(或者微软的其它邮件客户端如:Outlook Express.Windows Live Mail)的邮件文件(.eml格式)中提取各种电子邮件内容,使用LumiSoft.Net ...

  2. TPL实现Task.WhileAll扩展方法

    文章翻译整理自 Nikola Malovic 两篇博文: Task.WhileAll Awaitable task progress reporting 当 Task.WhenAll 遇见 Task. ...

  3. 如何把excel数据导入数据库

    这里介绍2种把excel数据导入oracle数据库的方法. 1. 在excel中生成sql语句. 1)在数据列的右侧,第一行的任何位置输入="insert into table(xx,yyy ...

  4. Linux 进程

    Linux 进程 在用户空间,进程是由进程标识符(PID)表示的.从用户的角度来看,一个 PID 是一个数字值,可惟一标识一个进程.一个 PID 在进程的整个生命期间不会更改,但 PID 可以在进程销 ...

  5. 深入探索AngularJS(持续更新)

    数据双向绑定并不是Angular最出彩的地方.大部分对AngularJs的介绍都偏重于使用,使用的学习只是学了AngularJs的API,而那只能AngularJs的很小一部分.随着使用越来越深,系统 ...

  6. paip.提升性能---并行多核编程哈的数据结构list,set,map

    paip.提升性能---并行多核编程哈的数据结构list,set,map vector/copyonwritearraylist 都是线程安全的. 或者经过包装的list ::: collection ...

  7. atitit.为什么java体系开发效率这样低的原因and解决

    atitit.为什么java体系开发效率这样低的原因and解决 #---开发理念问题(影响度:很大的,2-3倍效率) mvc<>webform server control ajax< ...

  8. paip.自适应网页设计 跟 响应式 设计方法与工具补充(2)o54

    paip.自适应网页设计 跟 响应式 设计方法与工具补充(2)o54 #-----响应式 设计框架 Bootstrap比较热门. Foundation 号称是世界上最先进的响应式前端框架. #---绝 ...

  9. Windows环境下32位汇编语言程序设计(典藏版)

    Windows环境下32位汇编语言程序设计(典藏版)(含CD光盘1张)(年,经典再现!) 罗云彬 著 ISBN 978-7-121-20759-4 2013年7月出版 定价:99.00元 756页 1 ...

  10. 更改Windows系统的密码之后,SQL Server 2008服务无法启动

    问题:更改Windows操作系统的密码之后,SQL Server 2008服务无法启动. 原因:SQL Server服务需要使用操作系统的某个登录账户. 解决:需要在服务的属性窗口中修改账户密码,然后 ...