本文实践代码托管在:https://github.com/leishiguang/spring-cloud-demo
嗯,先说说注册中心,假如没有注册中心,如何管理多个服务?我们可能会在客户端提前配置服务端的地址。
但这样,没有注册中心,带来的问题有:
那么,注册中心的存在意义,就是为了:
集成和配置的一些 tips:
spring.application.name,服务名称
server.port,服务端口
eureka.instance.hostname,当前实例名称
eureka.instance.intance-id,实例的id
eureka.client.fetch-registry,是否要拉取 eureka 的服务列表?
eureka.client.register-with-eureka,是否要把自己注册在eureka?
eureka.client.service-url.defalutZone,要选择的注册中心?
eureka.server.wait-time-in-ms-when-sync-empty,服务要同步数据的等待时间
eureka.server.enable-self-reservation,自我保护机制,是不是防止网络颤动时的服务下线,这一步虽然确保了自身的健壮性,但可能会保留已宕机的服务,好在有别的组件弥补了这部分的不足
eureka.server.peer-eureka-nods-update-interval-ms,服务同步时间,可以稍微设置长一些,因为我们不需要它那么快速的去同步
defaultZone 是一个区域的概念,可以指定对应的地区,比较适用于较大范围的服务器,这样客户端会优先调用同地区的服务,比如这么一个配置:
eureka.client.service-url.defalutZone = http://localhost:10000/eureka
eureka.client.service-url.zone1 = http://localhost:10002/eureka
eureka.client.availability-zones.china
:zone1
这样,在 china 节点,就会优先调用 10002 上注册的服务,如果调用不到,才会调用 10000 上注册的
嗯,顺利启动之后,便可以在配置好的服务地址,看到服务信息哦,如:
这时,只是 eureka 服务端启动了,如果要进行服务,还需要有:
那么,eureka 客户端的集成:
http://服务名/
替代 ip 和 port,如:@Autowired
private RestTemplate restTemplate;
@GetMapping("index")
public Object getIndex(){
return restTemplate.getForObject("http://HELLOSERVER/",String.class,"");
}
那么,eureka 的核心知识有哪些呢?
详细源码解析,下回分解 ?
前面说到,eureka 中,当服务提供方有多个的时候,要按什么样的规则去调用呢?
好比 nginx 可以对请求进行分流。当请求已经进入服务端之后,该服务端又要作为服务的调用方,去调用其它服务。这时候,要怎么做负载均衡呢?
这就是 ribbon 为我们做的事情,客户端负载均衡。
如何集成呢?这儿先看看如何在脱离 eureka 的情况下,进行 ribbon 负载均衡…
那么,这里涉及到的 ribbon 核心知识:
ribbon 中,如果要自定义策略,实现 IRule 接口即可,官方提供了这么些负载均衡策略:
嗯,Ribbon 与 RestTemplate,前面介绍时,使用的是 LoadBanlancerClient,实际上,Ribbon 可以与 RestTemplate 很好的结合:
@Bean
@LoadBalanced
public RestTemplate template(){ return new RestTemplte() }
这样,就可以和 eureka 一样,通过服务名进行调用了。
详细源码解析,下回分解 ?
在微服务中,一个请求有可能是多个微服务协同处理的,多个微服务相互依赖。这时候,如果某个服务超时、网络不通,导致调用者阻塞,怎么办?总不能够全部的请求都积压在这一个服务上,占用大量资源,导致系统雪崩吧?
那,如何保护系统呢?一个服务不能用就不能用,不能因为这样,全盘系统都不能用了。
于是:
好比,在使用淘宝时,如果请求太大,会提示:服务忙,请稍后再试。
嗯,这三个东西要自己实现,还是有些麻烦的。那么,hystrix 就是现成可用的。
如何集成?
这儿要注意,熔断是在服务调用者端进行设计哦…
具体的配置,还参考示例…
那么,关于 hystrix 的核心:
用 RestTemplte 可能还有些不顺手,那么,是不是可以有类似于普通的 java 接口调用呢?这就是 Feign 的来源了,它让 web 接口调用和普通 java 接口一样便携。
spring cloud 对 Feign 的增强和改造:
那么,要怎么使用(集成)呢?
tips:在定义接口的时候,也可以与 hystrix 集成,添加 fallback 哦,在配置文件中加入 feign.hystrix.enabled=true
即可,具体的参见代码实践…
关于 Feign 的使用,接口定义的示例:
@Component
@FeignClient(name="helloserver",fallback = HelloDemoFallback.class)
public interface HelloDemoService {
@RequestMapping(value = "",method = RequestMethod.GET)
public String index();
}
使用示例:
@RestController
public class CustomerController {
@Autowired
HelloDemoService helloDemoService;
@GetMapping("index")
public Object getIndex(){
return helloDemoService.index();
}
}
那么,核心原理,比如如何初始化?
其本质是使用 FeignClientFactoryBean 生成代理对象,并交给 spring 托管…
后端的服务提供者越来越多了,各个服务者之间调用倒是挺开心的。但是,对于外部来说呢?
zuul 网关应运而生,专门用以解决类似于上述典型问题。所有的外部请求先通过这个微服务网关,客户端只和网关进行交互,然后由网关进行各个微服务的调用。
这个过程就有点儿类似于 nginx 了,而它的特性有:
如果把整个微服务当作我们的家,网关就相当于是大门。
这儿容灾切换,指的是异地存在多个服务器,比如华南区、华北区,这种如果有一个区域宕机了,将自动把服务切换过去。尽量减少一个区域崩了之后,就完全无法用了。
zuul 本质上就是一个 web 应用,是一个 API Gateway 服务器。zuul 可以提供动态路由,监控,弹性,安全等边缘服务的框架。相当于是服务和所有 web 请求的大门。
zuul 能做什么?
如何使用(集成)呢?
@EnableZuulProxy,实际上也继承了 @EnableZuulServer 的自动装配,扩展了 Server 的功能,主要区别是 Proxy 用动态代理的方式去转发路由。
zuul.host.connect-timeout-millis: http请求超时时间
zuul.host.socket-timeout-millis:socket请求超时时间
zuul.host.max-total-connections:最大连接数(连接池大小)
zuul.host.max-per-route-connections:每个 host 的最大连接数
zuul.ribbon-isolation-strategy: 隔离模式
zuul.semaphore.max-semaphores:最大并发数
zuul.routes... 路由配置
那么,zuul 的核心知识:
zuul 的初始化和执行流程
zuul 的路由定位流程
.http 的执行流程
前置 filters,
routing filters,用来执行请求,比如用 ribbon 封装,就是有一个 ribbon 的 routing filters。
post filters,在请求之后执行,用于返回数据。
通常,如果有任意 filter 出错了,都会进到 error filter。
zuul 的初始化过程:
zuul 的 filter 执行流程:
zuul 的路由定位流程:
zuul 的请求流程:
具体的源代码分析,下回分解咯~
如果要扩展 zuul 功能,比如登陆验证,就看实践代码…
一次完整的 spring cloud demo 实战,跳转 https://github.com/leishiguang/spring-cloud-demo
目前正在不断完善中…