springcloud 中有两种调用方式,RestTemplate、Fegin。RestTemplate 由 spring 提供,而 Fegin 是 springcloud 提供,具体来说当然 Fegin 更好用,但是今天使用 RestTemplate
RestTemplate 简介
Spring'scentral class for synchronous client-side HTTP access.It simplifies communication with HTTPservers, and enforces RESTful principles. Ithandles HTTP connections, leaving application code to provide URLs(with possible template variables) andextract results.
简单说就是:简化了发起 HTTP 请求以及处理响应的过程,并且支持 REST 风格,为什么是简化呢?因为他比传统的 URLConnection 建立连接简化太多
RestTemplate 的 get 方法有以上几个,常见的是: getForEntity() 和 getForObject()
首先看 getForEntity() 的返回值类型 ResponseEntity
ResponseEntity getForEntity()
可以看到它继承了 HttpEntity,封装了返回的响应信息,包括响应状态,响应头和响应体。但是,通常情况下我们并不想要 Http 请求的全部信息,只需要相应体即可,对于这种情况,RestTemplate 提供了 getForObject() 方法用来只获取响应体信息,非常方便
客户端负载均衡
负载均衡是我们处理高并发、缓解网络压力和进行服务端扩容的重要手段之一,但是一般情况下我们所说的负载均衡通常都是指服务端负载均衡
Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡器,当我们将 Ribbon 和 Eureka 一起使用时,Ribbon 会从 Eureka 注册中心去获取服务端列表,然后进行轮询访问以到达负载均衡的作用,客户端负载均衡中也需要心跳机制去维护服务端清单的有效性,当然这个过程需要配合服务注册中心一起完成
客户端负载均衡和服务端负载均衡最大的区别在于服务清单所存储的位置。在客户端负载均衡中,所有的客户端节点都有一份自己要访问的服务端清单,这些清单统统都是从 Eureka 服务注册中心获取的。在 springcloud 中我们如果想要使用客户端负载均衡,方法很简单,开启@LoadBalanced
注解即可,这样客户端在发起请求的时候会先自行选择一个服务端,向该服务端发起请求,从而实现负载均衡
服务的集群部署
首先我们通过修改服务的端口来启动两个服务
说明:通过修改端口号,然后多启动几个服务就可以了,但是要注意设置下启动类
将single instance only 勾去掉,使得支持多开
然后刷新下注册中心我们可以看到下图:
8081 和 8082 两个服务构成简单的集群
服务调用
在 springcloud 中我们如果想要使用客户端负载均衡,方法很简单,开启@LoadBalanced
注解即可,现在使用springcloud-order
服务调用springcloud-emp
服务,再 order 启动类里面注入 RestTemplate,并添加@LoadBalanced
注解
@SpringBootApplication@EnableEurekaClientpublic class ApplicationOrder { public static void main(String[] args) { SpringApplication.run(ApplicationOrder.class, args); } @Bean @LoadBalanced //该注解可以让该resttemplate在请求时拥有客户端负载均衡的能力 public RestTemplate restTemplate(){ return new RestTemplate(); }}
使用 RestTemplate 调用服务springcloud-emp
@RestControllerpublic class OrderController { /** * springcloud 中有两种调用方式:restTemplate,fegin(springcloud) * restTemplate 是spring 提供,默认已经整合了 ribbon 负载均衡器 * restTemplate 底层就是用的httpclient */ @Autowired RestTemplate restTemplate; @RequestMapping("/orderinfo") public String orderinfo() { //两种调用,一种是服务别名,另一种直接调用 //String url = "http://127.0.0.1:8101/empinfo"; String url = "http://springcloud-emp/empinfo"; String result = restTemplate.getForObject(url, String.class); return result; }}
springcloud-emp
服务代码如下
@RestControllerpublic class EmpController { @Value("${server.port}") private String port; @RequestMapping("/empinfo") public String getEmp(){ return "hello springcloud. ~~一个穷屌丝!:"+port; }}
然后访问springcloud-order
服务,springcloud-order
服务再调用springcloud-emp
服务,多次访问springcloud-order
服务会看到负载均衡的效果
项目结构如下:
源码参考地址: