通讯的方式主要有两种,Http 和 RPCjava
SpringCloud使用的是Http方式通讯, Dubbo的通讯方式是RPCweb
记录学习SpringCloud的restful方式: RestTemplate (本篇)、Feignspring
RestTemplate 相似 HttpClient,使用更简洁一些,下面一步一步学习服务器
在以前学习中;在E:/MyCloud的中已经存在名为eureka的注册中心,和一个名为client的服务restful
不用管,为了区分开学习,从新建两个服务,一个product,一个order,这里不说怎么建了,IDEA一键生成便可(注册中心一直是开启状态)并发
product 服务端口不设置,在启动项中设置,方即可以开启不一样端口的多服务,在第(四)篇有记录,启动一个8081 和 一个8082,便于测试app
yml中配置 : (spring.application.name=product 标识name后面会用到)负载均衡
spring: application: name: product eureka: client: service-url: defaultZone: http://localhost:8761/eureka/
加一个简单的接口,product 服务这块就完成了,两个应用都启动(8081,8082)dom
@RestController public class ProductsController { @GetMapping("/products") public String products(){ return "hello,this is products"; } }
在注册中心,能够发现服务,PRODUCT学习
order 服务 端口设置8083,spring.application.name=order,其余基础yml配置与product一致
访问product服务中的接口的几种方式,以下: Controller 代码
import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import static java.lang.String.format; @RestController @Slf4j public class OrderController { //第二种方式 使用 @Autowired private LoadBalancerClient client; //第三种方式 使用 @Autowired private RestTemplate restTemplate; @GetMapping("/get") public String getProducts(){ RestTemplate restTemplate=new RestTemplate(); //第一种方式 直接请求 getForObject(请求url,返回类型) String first_type=restTemplate.getForObject("http://localhost:8081/products",String.class); log.info("first response={}",first_type); //若是肯定就那个一个,用最简单的就行了 //若是product项目启动不一样端口服务,用负载均衡方式,那么第一种方式就比较死气,恰好指向的那个挂了,就很差了 //第二种方式 经过注册中心,1.获取host+port,2.获取uri 并发出请求 //choose的参数为注册中心Instances currently registered with Eureka下面Application的名字 //服务会本身选择一个服务接口发送请求,负载均衡的方式选择有不少,好比随机,顺序等等 ServiceInstance instance=client.choose("PRODUCT"); String url= format("http://%s:%s",instance.getHost(),instance.getPort())+"/products"; String second_type_1=restTemplate.getForObject(url,String.class); System.out.println(second_type_1); String second_type_2=restTemplate.getForObject(instance.getUri()+"/products",String.class); System.out.println(second_type_2); //第三种方式,相似第二种方式,须要将restTemplate以注解@bean方式注入,并加上@LoadBalanced注解 //请求拼接http:// + Application的名字 + 接口名字 String third_type=restTemplate.getForObject("http://PRODUCT/products",String.class); System.out.println(third_type); return ""; } }
第三种使用到RestTemplateConfig的代码:
import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; @Component public class RestTemplateConfig { @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } }
Eureka属于客户端发现,他的负载均衡属于客户端向服务器获取已经注册的可用服务信息,而后根据其负载均衡的策略(随机,顺序等),选其中一个,发送请求,这个过程是在客户端完成的,属于软负载,并不须要服务器的参与
SpringCloud中客户端负载均衡组件是Ribbon,有上面的RestTemplate,还有Feign、zuul等后面继续学习,都使用到Ribbon
Ribbon实现软负载有三点核心:
服务发现 : 找服务,就像上面测试的依据application的名字,找到是哪一个服务
服务选择规则 : 从多个服务中,选择一个有效的服务
服务监听 : 检测失效的服务,将不会再去命中失效的服务
Ribbon的主要组件: ServerList、IRule、ServerListFilter等
Ribbon流程 : 经过ServerList获取全部可用服务列表,而后经过ServerListFilter过滤一部分服务, 最后使用IRule选择一个目标
查看Ribbon的源码,发现ServerList方法是过期的,使用另外一个getAllServers方法
IRule默认的命中方式是天然顺序的方式,若是想改变方式能够,参考官网的文档以下:
那么咱们在yml中加入以下配置: 随机方式(其余方式能够在实现IRule接口的方法中查找,路径须写全)
PRODUCT: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
文档能够找中文的,也能够看官方英文的,看本身爱好,耐心很重要,url: spring.io
本篇不记录更多了,一段一段消化,下篇再继续Feign的学习
------------------------------------------------------------