四、客户端负载均衡器Ribbon
4.1.SpringCloud负载均衡器说明
在SpringCloud第一代中使用Ribbon、SpringCloud第二代中直接采用自研发loadbalancer即可,默认使用的Ribbon。
使用方式非常简单:
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
4.2.LoadBalancerClient负载均衡器
@RequestMapping("/loadBalancerClient")
public Object loadBalancerClient() {
return loadBalancerClient.choose("meitemayikt-member");
}
底层默认原理是调用ribbon的实现客户端负载均衡器。
4.3.本地负载均衡
本地负载均衡器基本的概念:我们的消费者服务从我们的注册中心获取到集群地址列表,缓存到本地,让后本地采用负载均衡策略(轮训、随机、权重等),实现本地的rpc远程的。
4.3.1.本地负载均衡器与Nginx的区别
Nginx是客户端所有的请求统一都交给我们的Nginx处理,让后在由Nginx实现负载均衡转发,属于服务器端负载均衡器。
本地负载均衡器是从注册中心获取到集群地址列表,本地实现负载均衡算法,既本地负载均衡器。
应用场景:
Nginx属于服务器负载均衡,应用于Tomcat/Jetty服务器等,而我们的本地负载均衡器,应用于在微服务架构中rpc框架中,rest、openfeign、dubbo。
五、OpenFeign客户端
5.1.概述
1.OpenFeign是一个Web声明式的Http客户端调用工具,提供接口和注解形式调用。
2.SpringCloud第一代采用feign第二代采用openfeign
3.openfeign客户端作用:是一个Web声明式的Http客户端远程调用工具,底层是封装HttpClient技术。
4.Openfeign属于SPringleCloud自己研发,而feign是netflix代码写法几乎是没有任何变化。
5.注意feign客户端调用的事项:如果请求参数没有加上注解的话,默认采用post请求发送。
6.Openfeign默认是支持负载均衡,ribbon。
5.2.练习
Maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies>
<!-- springboot 整合web组件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
</dependencies>
会员服务接口
public interface MemberService {
/**
* 提供会员接口
*
* @param userId
* @return
*/
@GetMapping("/getUser")
String getUser(@RequestParam("userId") Long userId);
}
@RestController
public class MemberServiceImpl implements MemberService {
@Value("${server.port}")
private String serverPort;
@Override
public String getUser(Long userId) {
return "我是会员服务端口号为:" + serverPort;
}
}
订单服务
@RestController
public class OrderService {
@Autowired
private MemberServiceFeign memberServiceFeign;
/**
* 订单调用会员
*
* @return
*/
@GetMapping("/orderToMember")
public String orderToMember() {
String result = memberServiceFeign.getUser(10L);
return "我是订单服务,调用会员服务接口返回结果:" + result;
}
}
@FeignClient(name = "xinzhi-member")
public interface MemberServiceFeign extends MemberService {
}
1、想要远程调用别的服务
1)、引入open-feign
2)、编写一个接口,告诉SpringCloud这个接口需要调用远程服务
1、声明接口的每一个方法都是调用哪个远程服务的那个请求
@FeignClient("gulimall-coupon")
public interface CouponFeignService {
@RequestMapping("/coupon/coupon/member/list")
public R membercoupons();
}
3)、开启远程调用功能
@EnableFeignClients(basePackages = "com.atguigu.gulimall.member.feign")
六、Gateway
6.1.什么是微服务网关
1)微服务网关是整个微服务API请求的入口,可以实现过滤Api接口。
2)作用:可以实现用户的验证登录、解决跨域、日志拦截、权限控制、限流、熔断、负载均衡、黑名单与白名单机制等。
3)微服务中的架构模式采用前后端分离,前端调用接口地址都能够被抓包分析到。
4)在微服务中,我们所有的企业入口必须先经过Api网关,经过Api网关转发到真实的服务器中。
5)如果此时需要添加验证会话信息:
传统的方式我们可以使用过滤器拦截用户会话信息,这个过程所有的服务器都必须写入该验证会话登录的代码。
6.2.过滤器与网关的区别
过滤器适合于单个服务实现过滤请求;
网关拦截整个的微服务实现过滤请求,能够解决整个微服务中冗余代码。
过滤器是局部拦截,网关实现全局拦截。
6.3.Zuul与Gateway有哪些区别
1.Zuul网关属于netfix公司开源的产品,属于第一代微服务网关
Gateway属于SpringCloud自研发的网关框架,属于第二代微服务网关
2.Zuul网关底层基于Servlet实现的,阻塞式的Api, 不支持长连接。
SpringCloud Gateway基于Spring5构建,能够实现响应式非阻塞式的Api,支持长连接,能够更好的整合Spring体系的产品,依赖SpringBoot-WebFlux。
6.4.Gateway环境快速搭建
不引入WEB依赖
Maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
</dependencies>
application配置
server:
port: 80
####服务网关名称
spring:
application:
name: xinzhi-gateway
cloud:
gateway:
discovery:
locator:
####开启以服务id去注册中心上获取转发地址
enabled: true
###路由策略
routes:
###路由id
- id: xinzhi
####转发http://www.mayikt.com/
uri: http://www.baidu.com/
###匹配规则
predicates:
- Path=/xinzhi/**
###路由id
- id: member
#### 基于lb负载均衡形式转发
uri: lb://xinzhi-member
filters:
- StripPrefix=1
###匹配规则
predicates:
- Path=/member/**
nacos:
discovery:
server-addr: 127.0.0.1:8848
6.5.Nginx与网关的区别
微服务网关能够做的事情,Nginx也可以实现。
**相同点:**都是可以实现对api接口的拦截,负载均衡、反向代理、请求过滤等,可以实现和网关一样的效果。
不同点:
Nginx采用C语言编写的
在微服务领域中,都是自己语言编写的,比如我们使用java构建微服务项目,Gateway就是java语言编写的。
毕竟Gateway属于Java语言编写的, 能够更好对微服务实现扩展功能,相比Nginx如果想实现扩展功能需要结合Nginx+Lua语言等。
Nginx实现负载均衡的原理:属于服务器端负载均衡器。
Gateway实现负载均衡原理:采用本地负载均衡器的形式。
6.6.Gateway集群
1.如果我们使用网关宕机了,会出现什么情况?也就是说会导致我们整个微服务无法实现通讯。
答:网关实现集群,基于Nginx实现即可。
2.网关实现了集群如何访问?
答:使用nginx或者lvs虚拟vip。客户端访问lvs虚拟vip,随机绑定一个Nginx,每个Nginx配置一样。
6.7.匹配规则
通过时间匹配
# 之后
# - After=2021-07-13T08:35:00+08:00[Asia/Shanghai]
# 之前
# - Before=2018-01-20T06:06:06+08:00[Asia/Shanghai]
# 之间
# - Between=2018-01-20T06:06:06+08:00[Asia/Shanghai], 2019-01-20T06:06:06+08:00[Asia/Shanghai]
请求时间在 2021 年 7 月 13 日 8 点 35分 0 秒之后的所有请求都转发到地址http://ityouknow.com
。+08:00
是指时间和 UTC 时间相差八个小时,时间地区为Asia/Shanghai
。
通过 Cookie 匹配
通过 Host 匹配
通过请求方式匹配
可以通过是 POST、GET、PUT、DELETE 等不同的请求方式来进行路由。
- id: method_route
uri: http://ityouknow.com
predicates:
- Method=GET
通过请求路径匹配
- id: host_route
uri: http://ityouknow.com
predicates:
- Path=/foo/{segment}
通过请求参数匹配
Query Route Predicate 支持传入两个参数,一个是属性名一个为属性值,属性值可以是正则表达式。
- id: query_route
uri: http://ityouknow.com
predicates:
- Query=smile
# - Query=keep, pu.
通过请求 ip 地址进行匹配
- id: remoteaddr_route
uri: http://ityouknow.com
predicates:
- RemoteAddr=192.168.1.1/24
组合使用
各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配。
- id: host_foo_path_headers_to_httpbin
uri: http://ityouknow.com
predicates:
- Host=**.foo.org
- Path=/headers
- Method=GET
- Header=X-Request-Id, \d+
- Query=foo, ba.
- Query=baz
- Cookie=chocolate, ch.p
- After=2018-01-20T06:06:06+08:00[Asia/Shanghai]