springcloud总结
springcloud总结:
1.服务架构的演变
1>当我们的网站的并发量在100左右的时候,选择单体架构,直接采用表现层,服务层,数据层,(三层架构)就可以搞定!
2>商城的1000并发量 ,根据Tomcat来计算,需要使用2到3台tomcat,平均一台Tomcat可以负载300并发量
但是这些相同Tomcat来处理相同的项目,前面在使用一个负载均衡服务器来实现转发,但是这些tomcat
之间可以使用tomcat集群的的session复制的方式,进行通信!
3> 商城的10000并发量,上面的架构支撑不了,如果在使用第二种架构,性能可能会下降,因为session
在通信的时候,内网带宽的原因。
这个时候就需要分布式来支撑,分布式:把项目的每一个功能模块拆分成单个的系统,单独为每一个节点
添加服务器,需要系统之间的配置来完成业务逻辑
2.一旦把系统拆分成各个单独的服务的话,那么就会面临各个服务之间的调用问题?
服务的调用方式:
Rpc http 两种方式
rpc:这种调用方式有常见的WebService 和 dubbo
http:这种方式其实是一种网络协议,一般是方式Rest风格的调用采用这种方式
如果我们选择http方式进行服务之间的调用的话,那么就需要http的客户端工具,我们采用Spirng中的RestTemplate进行服务之间的调用
RestTemplate的使用方式:
1>.首先我们在项目中注册一个RestTemplate对象,可以在启动类中注册
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
2>.在测试类中直接注入这个对象,然后测试使用
@Test
public void httpGet() {
User user = this.restTemplate.getForObject("http://localhost/user/8", User.class);
System.out.println(user);
}
微服务
定义:SpringCloud也是一样,它将现在非常流行的一些技术整合到一起,实现了诸如:配置管理,服务发现,智能路由,负载均衡,熔断器,控制总线,集群状态等等功能
Eureka的实现步骤:
服务端:
1.首先是导入eureka的服务端的依赖
2.在启动类上加上一个注解表示这个是一个eureka的服务
3.在配置文件中的配置,配置主要是一个服务的地址(刚开始不然报错,地址就写自己,自己注册自己),还有一个是服务的名称,因为注册到
eureka中的服务都是需要配置一个名称的,因为eureak注册中心是需要记录你服务的名称的,才可以给服务调用者方便的提供服务!
还有一个是服务的端口号 一般是10086(呼叫中心)
服务消费方(客户端)
1.首先是导入依赖,导入eureka的客户端的依赖
2.在启动类上加一个注解EnabaleDiscoverClient依赖
3.配置服务名称
spring:
application:
name: user-service //配置名称,这个名称就是在服务注册中心的名称
配置地址:
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
服务提供方(客户端)
服务提供方和服务消费方一样的!!!!
ribbon负载均衡(负载均衡是基于erueka注册中心的!!!)
应用场景:举个例子当我们的服务提供方有多个的实例的时候,我们采用ribbon负载均衡的方式对服务进行调用
1.首先在服务的消费方引入负载均衡的依赖
2.在启动类的RestTemplate方法上添加一个@LoadBalance注解
3.把请求的路径修改成服务的id即可
String url="http://user-service/user/"+id
User user=restTemplate.getForObject(url,user.class);
return user;
Hystrix 服务的熔断
雪崩:就是服务的调用之间出现了级联的失败问题,加入一个请求到tomcat服务器以后,调用了一个服务,但是个服务依赖了另一个服务,但是这个服务已经挂了,但是用户是一直在访问,假如这个tomcat一共有1000个线程,但是就是因为这一个服务的出现了异常,把这1000个线程全部用完了,当有用户进来访问其他的服务的时候也是访问不了的,因为tomcat的线程已经满了,导致整个系统的崩溃,叫做雪崩效应,又叫做蝴蝶效应!
解决的方式:
1.线程的隔离+服务的降级
线程的隔离:
意思就是说,通过线程池把服务隔离起来,一个服务分配一个线程池,每一个线程池中假设分配10个线程,这个时候如果某一个服务出现了问题,那么只会占满该服务的线程池,不会影响到其他的线程池,所以就不影响到其他服务的调用!
服务的降级:
一旦一个请求进来以后,服务出现了异常 ,不会让用户处于一直等待状态,可以快速的结束这次请求,然后给予有好的提示!
或者说把更多的服务器资源去帮助这个服务!
触发服务的降级的原因:线程池已经满了,或者是请求超时了!
注意:在服务的消费方进行服务的降级处理,因为消费方是用来调用别的服务的!
使用步骤:
1. 首先在服务的消费方引入Hystrix的依赖
2. 在启动类中配置注解@EnableCircuitBreaker
3. 这个时候发现这个springcloud程序的客户端上有三个注解 @EnableCircuitBreaker @EnableDiscoveryClient @SpringbootApplication
所以这个spring官方就把这三个注解合成@SpringCloutApplication注解 于是一个标准的springcloud客户端程序需要这个注解!
4.配置 使用默认的配置就可以了,超时时长都是使用默认的时长就可以了!
5.开启服务的降级 一般是使用@HystrixCommand(fallbackMethod=失败方法名称) ,但是注意成功的方法和失败的方法的返回值类型和参数列表
都是一样的!
如下所示:
@RestController("user")
public class ConsumerController{
@Autowired
private RestTemplate restTemplate;
//定义方法
@GetMapping("{id}")
@HystrixCommand(fallbackMethod= "queryUserByIdFallBack")
public String queryUserById(@PathVariable("id") Long id){
String url="http://user-service/user"+id;
String user=restTemplate.getForObject(url,String.class);
return user;
}
//定义失败的方法
public String queryUserByIdFallBack(Long id){
return "服务正忙!"
}
}
Hystrix熔断器的原理:
熔断器有三个状态,close open halfopen 请求正常的情况下是close状态,就是熔断器关闭状态,假设在20次请求内有百分之五十的请求是
失败的,那么这个时候熔断器就是open状态,这个时候,在有请求进来的时候就是直接返回失败都是不会去尝试加载,过一段时间就会进入一个
halfopen半开的状态,他会让一部分请求进来,如果这些请求是好的,没有问题的,那么熔断器就会进入关闭状态,否则还是开启状态!
Feign技术:
Feign就是来解决了远程调用的问题,因为开发者觉得使用
String url="http://user-service/user/"+id
这种方式不是特别的方便而且在路径中user路径都是写死的,所以觉得不够优雅
所以Feign就是来解决这个问题的!!
表现:实际上我们是实现了一次远程调用,但是在controller中看不出来,在controller看出的只是调用了本地的一个方法
这样也就达到了Feign的单词的意思了 ,“欺骗” !
Feign 实现步骤:
实现调用的肯定是消费方,所以都是在消费方中操作!
1.首先在消费方中引入依赖 openFeign
2.在启动类中添加注解@EnableFeignClients 启用Feign的客户端
3.定义一个包叫做Client 定义了一个接口userClient,在接口中告诉了Feign的调用信息(服务的名称user-service,路径,参数,返回值)
这些信息和使用RestTemplate调用的时候信息是一样的,一个都没有少,只是使用了Springmvc这套语法体现出了这些信息
如下:
@FeignClient("user-service")
public interface userClient{
@GetMapping("user/{id}")
User queryById(ParthVariable("id") Long id);
}
4. 然后再controller中直接注入这个userClient,然后直接调用定义好的接口就可以了
如下:
@Autowired
private userClient client;
@GetMapping("{id}")
public User queryUserById(@PathVariable("id") Long id){
return client.queryById(id);
}
原理:这个里面的原理就是和mybatis一样的,底层使用动态代理的方式,根据接口帮我们写好了远程调用的代码了!
注意:1.OpenFeign的依赖中已经有了ribbon负载均衡的依赖和Hystrix的依赖,所以这两个依赖是不用再引入了!
2. Feign中的熔断机制和spirngcloud中的熔断机制的配置有点区别,如果使用,可以百度!
zuul网关:
zuul网关就是起到一个boss的作用,就是起到了一个路由和过滤的作用
一切请求都是经过网关,都是由网关来实现鉴权,动态路由的操作,zuul就是
我们的统一的入口!
实现步骤:
1.首先引入依赖
2.在启动类中添加一个注解@EnableZuulProxy 开启网关的功能
3.在配置文件中编写配置文件
server:
port: 10010
spring:
application:
name: api-getway #指定服务名
4.使用zuul来代理user-service服务
编写代理规则:
zuul:
routes:
user-service #这个是路由id,可以随便定义
path: /user-service/** # 这个是映射路径
url: http://127.0.0.1:8081 #映射路径对应的实际的url
面向服务的路由的配置:
在刚才的路由规则中,我们把路径对应的服务地址写死了,如果同一个服务有多个实例的话,显然就是不太合理了
,我们应该根据服务的名称,去eureka注册中心中查找服务对应的所有的实例列表,然后动态路由即可!!
实现步骤:
1.首先导入依赖,一个是网关的依赖,一个是eureka客户端的依赖
2.在启动类上添加@Enablezuulproxy 开启网关的功能,同时开启@EnableDiscoveryClient 开启eureka客户端发现功能
3.添加eureka配置,获取服务信息
eureka:
Client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true
ip-address: 127.0.0.1
4.修改映射配置,通过服务名称来获取,因为已经有了Eureka客户端,我们可以从Eureka中获取服务的地址信息
因此映射的时候无需指定ip,而是通过服务名称来获取该服务的实例,而且zool网关中已经集成了Ribbon
负载均衡的功能:
zuul:
routes:
user-service: #这里是路由id,可以随便写
path: /user-service/** #这里是映射路径
serviceId: user-service #指定服务名称
注意:路由的简化配置
zuul:
routes:
user-service: /user-service/** #这个是映射路径 前面的user-service是服务id
zuul网关的过滤器配置:
zuul网关的一个重要的共两个了就是实现请求鉴权,这个功能的实现技术就是过滤器
zuulFilter 是过滤器的顶级湖南卫视,在这里我们看下定义的四个方法
public abstract ZuulFilter implements IZuulFilter{
abstract public String filterType(); //过滤器的类型
abstract public int filterOrder(); //定义的是过滤器的顺序
boolean shouldFilter(); //来自IZuulFilter 要不要过滤
object run() throws zuulException; //定义的是过滤的逻辑
}
- shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行。
- run:过滤器的具体业务逻辑。
- filterType:返回字符串,代表过滤器的类型。包含以下4种:
- pre:请求在被路由之前执行
- routing:在路由请求时调用
- post:在routing和errror过滤器之后调用
- error:处理请求时发生错误调用
- filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。