作者:微信小助手
发布时间:2022-03-22T21:50:28
互联网时代,面对复杂业务,讲究 分而治之 。将一个大的单体系统拆分为若干个微服务,保证每个系统的职责单一,可以垂直深度扩展。 但是一个个独立的微服务像一座座孤岛,如何将他们串联起来,才能发挥最大价值。 这时,我们就要提微服务的生态圈。 那么微服务生态圈都有哪些模块?他们的作用分别是什么? 围绕这些功能模块, 那么这套生态规范都提供了哪些技术框架呢? Spring Boot 是Spring框架的扩展,提供更加 特点: 基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能。 项目地址:https://github.com/YunaiV/ruoyi-vue-pro Nacos 是阿里巴巴的开源的项目,全称 Naming Configuration Service ,专注于服务发现和配置管理领域。 Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。功能齐全,可以替换之前的 客户端语言方面目前支持 Java,go 、python、 C# 和 C++等主流语言 开源地址:https://github.com/alibaba/nacos Nacos 有一个控制台,可以帮助用户管理服务,监控服务状态、应用的配置管理。 集群化部署: 由于 Nacos 官方提供的集群部署架构图: https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html 在nacos的解压目录 这样保证客户端只需要写一次,由 Leader节点将数据同步到其他节点,保证各个节点的数据一致性 对于上层的SLB,我们可以采用 另外,借助Nginx的心跳检测,当某台 Nacos 服务挂掉后,SLB 会自动屏蔽,将流量切换到其他 Nacos 实例。 当然 客户端请求 VIP,然后请求打到了 OpenResty,由 OpenResty 转发给具体的某个 Nacos 节点。 OpenResty 只有一个节点提供服务,另一个暂停状态,如果 master 节点宕机,那 backup 接替继续工作。从而解决了单点故障问题。 Keepalived 作为一种高性能的服务器高可用或热备解决方案,用来防止服务器单点故障的发生。市面资料很多,下文链接是《Keepalived+Nginx部署方案》具体操作步骤 https://help.fanruan.com/finereport/doc-view-2905.html Spring Cloud Ribbon 基于 Netflix Ribbon 封装的负载均衡框架。内部集成了多种负载算法,如:随机、轮询等。 与注册中心打通,能自动获取服务提供者的地址列表。结合自身的负载算法,选择一个目标实例发起服务调用。 Ribbon 也提供了扩展接口,支持自定义负载均衡算法。 缺点: 调用方每次发起远程服务调用时,都需要填写 RestTemplate + Ribbon 每次发起远程服务调用时,都需要填写 Feign 是一个轻量级的 Restful HTTP 客户端,内嵌了 Ribbon 作为客户端的负载均衡 。面向接口编程,使用时只需要定义一个接口并加上 OpenFeign 是 依赖包: 其中, OpenFeign 默认等待接口返回数据的时间是 1 秒,超过这个时间就会报错。如果想调整这个时间,可以修改配置项 Dubbo Spring Cloud = Spring Cloud + Dubbo 特性: 依赖包: 注意:虽然是将 Dubbo 集成到了 Spring Cloud,增加了一些 几个重要的配置项: 分布式时代,一个复杂的系统被拆分为若干个微服务系统,每个系统都配置独立的域名肯定不合适。为了解决这个问题,网关便诞生了。 网关充当反向代理的角色,作为流量的第一入口,承载了很多基础的、公共的模块功能,如:流控、鉴权、监控、路由转发等。 Spring Cloud 生态早期的网关是 Netflix 公司的Zuul,后来Zuul社区停止了维护。官方后来推出了 Spring Cloud Gateway,其底层是基于 WebFlux 框架 ,而WebFlux框架的底层采用高性能通讯框架 Netty,性能是 Zuul 的 1.6 倍。 核心组件: 1、路由。 内部主要是负责转发规则。 2、断言(Predicate) 如果返回为true,当前路由才有效,才会路由到具体的服务。官方提供了很多 所有的路由断言工厂都是继承自 3、过滤器(Filter) 主要是请求、响应之间增加一些自定义的逻辑。按作用范围分为:全局和局部。全局是作用于所有的路由;而局部只是作用于某一个路由。 跟上面的断言类似,除了官方提供的过滤器,也支持自定义。 局部过滤器 :继承自 全局过滤器 :实现 依赖包: yaml 的配置示例:
Spring Cloud Alibaba
为我们提供了微服务化开发的一站式解决方案,我们只需要少量的Spring 注解
和 yaml配置
,便可以快速构建出一套微服务系统。真的是创业者的福音。
一、Spring Boot(服务基座)
丰富的注解
,根据 约定胜于配置 原则,与市场主流的开源框架打通, 设计了 Starter
和 AutoConfiguration
机制,简化配置流程,通过简单的jar包引入,快速具备组件集成能力。大大提高了程序员的开发效率。
二、Nacos(注册中心、分布式配置中心)
Spring Cloud Netflix Eureka
、Spring Cloud Config
、Spring Cloud Bus
,野心巨大。
Nacos
是单节点,无论做为注册中心
还是分布式配置中心
,一旦服务器挂了,作为底层服务引发的麻烦还是非常大的。如何保证其高可用?
nacos/conf
目录下,有配置文件cluster.conf
,每行配置成 ip:port。(一般配置3个或3个以上节点)
> 基于微服务的思想,构建在 B2C 电商场景下的项目实战。核心技术栈,是 Spring Boot + Dubbo 。未来,会重构成 Spring Cloud Alibaba 。
>
> 项目地址:<https://github.com/YunaiV/onemall>
# ip:port
200.8.9.16:8848
200.8.9.17:8848
200.8.9.18:8848Nginx
或者 OpenResty
,在 upstream 模块里配置 Nacos 的集群IP 地址列表,实现负载均衡功能。OpenResty
也可能成为单点故障,为了保证高可用,我们需要借助 Keepalived
三、RestTemplate + Ribbon (远程调用)
public class CustomRule extends AbstractLoadBalancerRule {
private AtomicInteger count = new AtomicInteger(0);
@Override
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
private Server choose(ILoadBalancer loadBalancer, Object key) {
List<Server> allServers = loadBalancer.getAllServers();
int requestNumber = count.incrementAndGet();
if (requestNumber >= Integer.MAX_VALUE) {
count = new AtomicInteger(0);
}
if (null != allServers) {
int size = allServers.size();
if (size > 0) {
int index = requestNumber % size;
Server server = allServers.get(index);
if (null == server || !server.isAlive()) {
return null;
}
return server;
}
}
return null;
}
}远程目标地址
,还要配置各种参数,非常麻烦,不是很方便// 注册到Nacos的应用名称
private final String SERVER_URL = "http://nacos-provider-demo";
@Resource
private RestTemplate restTemplate;
@RequestMapping("/hello")
public String hello() {
// 远程服务调用
return restTemplate.getForObject(SERVER_URL + "/hello", String.class);
}四、OpenFeign(远程调用)
远程目标地址
,还要配置各种参数,非常麻烦。@FeignClient
注解,非常方便。Feign
的增强版。对 Feign 进一步封装,支持 Spring MVC 的标准注解和HttpMessageConverts<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
@FeignClient(value = "${provider.name}")
public interface OrderService {
// 调用服务提供者的 /create_order 接口
@RequestMapping(value = "/create_order",method = RequestMethod.GET)
public String createOrder();@FeignClient(value = "${provider.name}")
定义了服务提供方的工程名,底层自动打通了注册中心,会拿到 artifactId
对应的IP列表,根据一定的负载均衡算法,可以将请求打到目标服务器上。feign.client.config.default.readTimeout
五、Dubbo Spring Cloud(远程调用)
RestTemplate + Ribbon
和 OpenFeign
都是基于HTTP协议调用远程接口。而 Dubbo Spring Cloud
是基于 TCP 协议来调用远程接口。相比 HTTP 的大量的请求头,TCP 更轻量级。
面向接口
,支持 TCP 轻量级协议
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>注解
和 yaml
配置项,开发更方便,但大部分调用玩法还是遵守 Dubbo 框架那一套。
六、Spring Cloud Gateway(网关)
内置路由断言
,如果满足不了你的诉求,也可以自定义路由断言工厂
。AbstractRoutePredicateFactory
,自定义类的命名也有固定规则,“配置名”+RoutePredicateFactory
。这样,在yaml配置时,只需要写前面定义的配置名
即可。AbstractGatewayFilterFactory
,自定义类的命名也有固定规则,“配置名”+GatewayFilterFactory
。这样,在yaml配置时,只需要写前面定义的配置名
即可。GlobalFilter
,Ordered
两个接口,实现逻辑跟上面的局部过滤器类似。这里就不展开了。其中的 Ordered
接口主要是负责优先级,数值越小,优先级越高。<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>spring:
cloud:
gateway:
routes: #路由,可配置多个
- id: user_route # 路由id 唯一即可,默认是UUID
uri: lb://user-server-sample # 匹配成功后提供的服务的地址
order: 1 # 路由优先级,数值越小优先级越高,默认0
predicates:
- Path=/user/** # 断言,路径匹配进行路由
# - User=0, 1000 # 自定义路由断言工厂 只允许查询id为0 - 1000之间的用户
# - Method=POST # 表示需要POST方式请求
# - Query=id, \d+ # 参数名id,正则表达式为\d+(一个或多个数字)
&nb