一、概述
1、微服务
微服务就是将单个应用程序分成多个小应用服务,每个服务单独运行,单独部署。核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底地去耦合,每一个微服务提供单个业务功能的服务。
2、spring cloud
分布式微服务架构下的一站式解决方案,是各个微服务架构落地技术的集合体。为各个微服务之间提供,配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等集成服务。
spring cloud与dubbo区别:SpringCloud抛弃了Dubbo的RPC通信,采用的是基于HTTP的REST方式。
二、Eureka服务注册与发现
1、是什么
Eureka是Netflix的一个子模块,也是核心模块之一。是微服务的注册与发现。功能类似于dubbo的注册中心,比如Zookeeper。Eureka 采用了 C-S 的设计架构,包含两个组件:Eureka Server和Eureka Client。Eureka Server提供服务注册服务,EurekaClient是一个Java客户端,用于简化Eureka Server的交互
2、自我保护
默认情况下,如果EurekaServer(注册中心)在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。Eureka通过“自我保护模式”来解决这个问题——当EurekaServer节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,EurekaServer就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。
3、构建步骤
1)创建注册中心微服务
a.pom引入Eureka服务端依赖spring-cloud-starter-eureka-server
b.application.yml配置Eureka
eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
#defaultZone设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。下面是单机和集群设置(集群就是设置除自己外其他Eureka服务地址)
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
defaultZone: http://eureka7001.com:7001/eureka/
c.spring boot 主启动类添加@EnableEurekaServer(EurekaServer服务器端)
2)修改微服务接口服务提供端
a.pom引入Eureka客户端依赖spring-cloud-starter-eureka和spring-cloud-starter-config
b.application.yml配置Eureka
spring:
application:
name: microservicecloud-dept #微服务访问名称
eureka:
client: #客户端注册进eureka服务列表内
service-url:
#访问集群地址
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
instance:
instance-id: microservicecloud-dept8002 #自定义服务名称信息
prefer-ip-address: true #访问路径可以显示IP地址
c.启动类加注解@EnableEurekaClient
3)修改微服务消费端
a.pom引入Eureka客户端依赖spring-cloud-starter-eureka和spring-cloud-starter-config
b.application.yml配置Eureka
eureka:
client:
register-with-eureka: false
service-url:
#访问集群地址
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
c.启动类加注解@EnableEurekaClient
c.创建配置bean
@Configuration
public class ConfigBean
{
@Bean
public RestTemplate getRestTemplate()
{
return new RestTemplate();
}
}
e.controller调用
private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";
@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);
}
三、Ribbon负载均衡
1、是什么
Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡。
2、构建步骤
1)修改微服务消费端
a.pom引入依赖spring-cloud-starter-ribbon
b.修改配置bean,使用@LoadBalanced注解
@Configuration
public class ConfigBean
{
@Bean
@LoadBalanced
public RestTemplate getRestTemplate()
{
return new RestTemplate();
}
}
3、修改默认负载算法
修改配置bean,增加IRule。总共有7种算法,默认是轮询。
RoundRobinRule 轮询
RandomRule 随机
AvailabilityFilteringRule 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,还有并发的连接数超过阈值的服务,然后对剩余的服务列表进行轮询
WeightedResponseTimeRule 权重 根据平均响应时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越高。刚启动时,如果统计信息不足,则使用轮询策略,等信息足够,切换到 WeightedResponseTimeRule
RetryRule 重试 先按照轮询策略获取服务,如果获取失败则在指定时间内重试,获取可用服务
BestAvailableRule 选过滤掉多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
ZoneAvoidanceRule 符合判断server所在区域的性能和server的可用性选择服务
@Configuration
public class ConfigBean
{
@Bean
@LoadBalanced//Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具。
public RestTemplate getRestTemplate()
{
return new RestTemplate();
}
@Bean
public IRule myRule()
{
//return new RoundRobinRule();
//return new RandomRule();//达到的目的,用我们重新选择的随机算法替代默认的轮询。
return new RoundRobinRule();
}
}
自定义负载算法,需继承AbstractLoadBalancerRule,修改choose(ILoadBalancer lb, Object key)实现,修改上面configbean的IRule使用自定义对象。
package com.atguigu.springcloud.cfgbeans;
import java.util.List;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
public class RandomRule_ZY extends AbstractLoadBalancerRule
{
private int total = 0; // 总共被调用的次数,目前要求每台被调用5次
private int currentIndex = 0; // 当前提供服务的机器号
public Server choose(ILoadBalancer lb, Object key)
{
if (lb == null) {
return null;
}
Server server = null;
while (server == null) {
if (Thread.interrupted()) {
return null;
}
List<Server> upList = lb.getReachableServers();
List<Server> allList = lb.getAllServers();
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
// int index = rand.nextInt(serverCount);// java.util.Random().nextInt(3);
// server = upList.get(index);
if(total < 5)
{
server = upList.get(currentIndex);
total++;
}else {
total = 0;
currentIndex++;
if(currentIndex >= upList.size())
{
currentIndex = 0;
}
}
if (server == null) {
Thread.yield();
continue;
}
if (server.isAlive()) {
return (server);
}
// Shouldn't actually happen.. but must be transient or a bug.
server = null;
Thread.yield();
}
return server;
}
@Override
public Server choose(Object key)
{
return choose(getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig)
{
}
}
四、Feign声明式服务调用
1、是什么
Feign是一个声明式的Web服务客户端,使得编写Web服务客户端变得非常容易,只需要创建一个接口,然后在上面添加注解即可。Feign自带ribbon负载。
2、构建步骤
1)修改微服务消费端
a.pom引入依赖spring-cloud-starter-feign
b.主启动类添加feigns扫描路径注解@EnableFeignClients(basePackages= {"com.test.springcloud"})
c.创建客户端调用Service接口
@FeignClient(value = "MICROSERVICECLOUD-DEPT")//调用的微服务名称
public interface DeptClientService
{
@RequestMapping(value = "/dept/get/{id}",method = RequestMethod.GET)
public Dept get(@PathVariable("id") long id);
@RequestMapping(value = "/dept/list",method = RequestMethod.GET)
public List<Dept> list();
@RequestMapping(value = "/dept/add",method = RequestMethod.POST)
public boolean add(Dept dept);
}
d.修改controller调用方式,相当于调用自己的service
五、Hystrix断路器
1、是什么
Hystrix是一个用于处理分布式系统的服务降级和熔断,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
服务熔断:当扇出链路的某个微服务不可用或者响应时间太长时,会熔断该节点微服务的调用,快速返回"错误"的响应信息。
服务降级:整体资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开启回来。
2、构建步骤(熔断和降级)
1)修改微服务消费端(rest api调用方式)
a.pom引入依赖spring-cloud-starter-hystrix
b.主启动类添加hystrixR熔断机制的支持注解@EnableCircuitBreaker
c.修改application.yml,添加feign: hystrix: enabled: true
d.修改http rest客户端调用接口添加@HystrixCommand注解和fallbackMethod对应方法
@RequestMapping(value = "/consumer/dept/get/{id}")
@HystrixCommand(fallbackMethod = "processHystrix_Get")
public Dept get(@PathVariable("id") Long id)
{
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
}
public Dept processHystrix_Get(@PathVariable("id") Long id)
{
return new Dept().setDeptno(id).setDname("该ID:" + id + "没有没有对应的信息,null--@HystrixCommand")
.setDb_source("no this database in MySQL");
}
2)修改微服务消费端(feign调用方式)
a.pom/yml和主启动类修改同上
b.新建一个实现了FallbackFactory接口的类DeptClientServiceFallbackFactory
@Component // 不要忘记添加,不要忘记添加
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService>
{
@Override
public DeptClientService create(Throwable throwable)
{
return new DeptClientService() {
@Override
public Dept get(long id)
{
return new Dept().setDeptno(id).setDname("该ID:" + id + "没有没有对应的信息,Consumer客户端提供的降级信息,此刻服务Provider已经关闭")
.setDb_source("no this database in MySQL");
}
@Override
public List<Dept> list()
{
return null;
}
@Override
public boolean add(Dept dept)
{
return false;
}
};
}
}
c.修改客户端调用Service接口,添加@FeignClient注解
@FeignClient(value = "MICROSERVICECLOUD-DEPT",fallbackFactory=DeptClientServiceFallbackFactory.class)
public interface DeptClientService
{
@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
public Dept get(@PathVariable("id") long id);
@RequestMapping(value = "/dept/list", method = RequestMethod.GET)
public List<Dept> list();
@RequestMapping(value = "/dept/add", method = RequestMethod.POST)
public boolean add(Dept dept);
}
3、构建步骤(服务监控hystrixDashboard)
1)新建监控微服务(9001)
a.pom引入依赖hystrix和 hystrix-dashboard
b.主启动类添加@EnableHystrixDashboard
c.所有Provider微服务提供者都需要监控依赖配置spring-boot-starter-actuator
d.填写监控地址
六、zuul路由网关
1、是什么
Zuul包含了对请求的路由和过滤两个最主要的功能:
其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础.
Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他微服务的消息,也即以后的访问微服务都是通过Zuul跳转后获得。
2、构建步骤
1)新建路由微服务(9527)
a.pom引入依赖spring-cloud-starter-eureka和 spring-cloud-starter-zuul
b.yml配置同服务提供者微服务配置一样
c.主启动类添加@EnableZuulProxy
d.路由访问地址:zuul地址:端口/微服务名称/controller访问路径,如http://myzuul.com:9527/microservicecloud-dept/dept/get/2
3、路由访问映射规则
对外隐藏真实的微服务名称,使用映射名称访问,修改yml:
zuul:
prefix: /zuultest #统一访问前缀,可选
ignored-services: "*" #忽略真实服务名称,使得不能通过微服务名称。多个用*,单个用真实微服务名称
routes:
mydept.serviceId: microservicecloud-dept #真实微服务名称
mydept.path: /mydept/** #映射服务名称