文章目录
一、集群、分布式和微服务
集群是指多个服务器通过局域网或其他连接方式进行连接,可以被看作同一台服务器,协同完成工作,来提高性能或可靠性。这些服务器,应该也可以通过同一个ip进行访问。
分布式是指一个业务拆成多个子业务,部署在不同的服务器上以提高效率。
集群和分布式并不冲突,也有分布式集群,即既将一个大的业务拆成不同的子业务,同一个子业务也可以用好几台机器。
微服务其实就是一个个分割而成的子业务,又或者说,一个个组件。在我眼里分布式主要侧重于“部署在不同的服务器”,指的是物理机器,而微服务就是指拆出来的子业务。
二、服务治理框架:Eureka
Eureka用于解决子系统之间的通讯问题。调用服务需要知道对方的ip和端口,如果写死在代码里,一旦某个服务换了ip,所有调用方都需要修改代码,非常麻烦。所以服务治理框架做的一件事其实就是“帮忙寻址”。
Eureka Client分为服务提供者和服务消费者,当然很多服务既是提供者也是消费者,如果只是消费者,那么不需要将自己的信息注册到Eureka中。如果是服务提供者,那么需要将自己的信息注册到Eureka中,消费者可以通过服务名来调用注册的服务,而不再通过IP地址来调用。
顺便提一嘴,consul也是为了实现相同的功能
三、远程调用工具类:RestTemplate
一般在使用SpringCloud的时候不需要自己手动创建HttpClient来进行远程调用。可以使用Spring封装好的RestTemplate工具类,使用起来很简单:
// 传统的方式,直接显示写死IP是不好的!
//private static final String REST_URL_PREFIX = "http://localhost:8001";
// 服务实例名
private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";
/**
* 使用 使用restTemplate访问restful接口非常的简单粗暴无脑。 (url, requestMap,
* ResponseBean.class)这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
*/
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/consumer/dept/add")
public boolean add(Dept dept) {
return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
}
四、Spring Cloud Feign
Spring Cloud Feign基于 Netflix Feign 实现,整合了 Spring Cloud Ribbon 与 Spring Cloud Hystrix, 除了整合这两者的强大功能之外,它还提供了声明式的服务调用(不再通过RestTemplate)。
使用方法:
1、SpringbootApplication启动类加上注解@EnableFeignClients
和@EnableDiscoveryClient
2、使用@FeignClient注解,name和value属性均可用于指定服务名;url属性一般用于调试程序,允许我们手动指定@FeignClient调用的地址;path属性定义当前FeignClient的路径统一前缀。
@FeignClient(name = "xxx", path = "xxx")
public interface xxxClient {
@Path("xxx/xxx") //需要访问的路径,注意前面写了path这里去前缀
@POST
Result<Yyy> xxx(Xxx xxx);
}
这里的访问路径用的是@Path(“xxx/xxx”),但是我看很多博客用的是@RequestMapping,暂时不是特别清楚这两个的区别…
此时上面的Client类已经可以在自己组件的其他类中使用@Autowired注入使用啦!
然后如果其他组件deploy了接口我们可以直接依赖的话,只需要在maven中引入依赖,client只需要如下这样就可以了,不需要在里面写任何方法:
@FeignClient(name = "xxx", path = "xxx")
public interface xxxClient extends XxxService{
}
五、简单了解负载Ribbon和Hystrix
Ribbon
客户端负载均衡(Ribbon)服务实例的清单在客户端,客户端进行负载均衡算法分配。(从上面的知识我们已经知道了:客户端可以从Eureka Server中得到一份服务清单,在发送请求时通过负载均衡算法,在多个服务器之间选择一个进行访问)
服务端负载均衡(Nginx)服务实例的清单在服务端,服务器进行负载均衡算法分配。
Ribbon是支持负载均衡,默认的负载均衡策略是轮询,我们也是可以根据自己实际的需求自定义负载均衡策略的。
@Configuration
public class MySelfRule
{
@Bean
public IRule myRule()
{
//return new RandomRule();// Ribbon默认是轮询,我自定义为随机
//return new RoundRobinRule();// Ribbon默认是轮询,我自定义为随机
return new RandomRule_ZY();// 我自定义为每台机器5次
}
}
实现起来也很简单:继承AbstractLoadBalancerRule
类,重写public Server choose(ILoadBalancer lb, Object key)
即可。
Hystrix
在高并发的情况下,由于单个服务的延迟,可能导致所有的请求都处于延迟状态,甚至在几秒钟就使服务处于负载饱和的状态,资源耗尽,直到不可用,最终导致这个分布式系统都不可用,这就是“雪崩”。
针对上述问题, Spring Cloud Hystrix实现了断路器、线程隔离等一系列服务保护功能。
Fallback(失败快速返回):当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝), 向调用方返回一个错误响应, 而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。
资源/依赖隔离(线程池隔离):它会为每一个依赖服务创建一个独立的线程池,这样就算某个依赖服务出现延迟过高的情况,也只是对该依赖服务的调用产生影响, 而不会拖慢其他的依赖服务。
Hystrix提供几个熔断关键参数:滑动窗口大小(20)、 熔断器开关间隔(5s)、错误率(50%)
每当20个请求中,有50%失败时,熔断器就会打开,此时再调用此服务,将会直接返回失败,不再调远程服务。直到5s钟之后,重新检测该触发条件,判断是否把熔断器关闭,或者继续打开。