互联网时代,面对复杂业务,讲究 分而治之。将一个大的单体系统拆分为若干个微服务,保证每个系统的职责单一,可以垂直深度扩展。
但是一个个独立的微服务像一座座孤岛,如何将他们串联起来,才能发挥最大价值。
这时,我们就要提微服务的生态圈。
那么微服务生态圈都有哪些模块?他们的作用分别是什么?
服务的注册、发现。生产者启动时,会将自己的信息注册上报,这样调用方只需连接注册中心,根据一定的负载算法,就可以与服务提供方建立连接,从而实现应用间的解耦。
围绕这些功能模块,Spring Cloud Alibaba 为我们提供了微服务化开发的一站式解决方案,我们只需要少量的Spring 注解 和 yaml配置,便可以快速构建出一套微服务系统。真的是创业者的福音。
那么这套生态规范都提供了哪些技术框架呢?
Spring Boot 是Spring框架的扩展,提供更加 丰富的注解,根据 约定胜于配置 原则,与市场主流的开源框架打通, 设计了 Starter 和 AutoConfiguration 机制,简化配置流程,通过简单的jar包引入,快速具备组件集成能力。大大提高了程序员的开发效率。
Nacos 是阿里巴巴的开源的项目,全称 Naming Configuration Service ,专注于服务发现和配置管理领域。
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。功能齐全,可以替换之前的 Spring Cloud Netflix Eureka、Spring Cloud Config、Spring Cloud Bus,野心巨大。
客户端语言方面目前支持 Java,go 、python、 C# 和 C++等主流语言
开源地址:https://github.com/alibaba/nacos
Nacos 有一个控制台,可以帮助用户管理服务,监控服务状态、应用的配置管理。
由于 Nacos 是单节点,无论做为注册中心还是分布式配置中心,一旦服务器挂了,作为底层服务引发的麻烦还是非常大的。如何保证其高可用?
Nacos 官方提供的集群部署架构图:
https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html
在nacos的解压目录nacos/conf目录下,有配置文件cluster.conf,每行配置成 ip:port。(一般配置3个或3个以上节点)
# ip:port
200.8.9.16:8848
200.8.9.17:8848
200.8.9.18:8848
这样保证客户端只需要写一次,由 Leader节点将数据同步到其他节点,保证各个节点的数据一致性
对于上层的SLB,我们可以采用 Nginx 或者 OpenResty,在 upstream 模块里配置 Nacos 的集群IP 地址列表,实现负载均衡功能。
另外,借助Nginx的心跳检测,当某台 Nacos 服务挂掉后,SLB 会自动屏蔽,将流量切换到其他 Nacos 实例。
当然 OpenResty 也可能成为单点故障,为了保证高可用,我们需要借助 Keepalived
客户端请求 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 也提供了扩展接口,支持自定义负载均衡算法。
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) {
ListallServers = 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);
}
RestTemplate + Ribbon 每次发起远程服务调用时,都需要填写远程目标地址,还要配置各种参数,非常麻烦。
Feign 是一个轻量级的 Restful HTTP 客户端,内嵌了 Ribbon 作为客户端的负载均衡。面向接口编程,使用时只需要定义一个接口并加上@FeignClient注解,非常方便。
OpenFeign 是 Feign 的增强版。对 Feign 进一步封装,支持 Spring MVC 的标准注解和HttpMessageConverts
org.springframework.cloud
spring-cloud-starter-openfeign
@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列表,根据一定的负载均衡算法,可以将请求打到目标服务器上。
OpenFeign 默认等待接口返回数据的时间是 1 秒,超过这个时间就会报错。如果想调整这个时间,可以修改配置项 feign.client.config.default.readTimeout
RestTemplate + Ribbon 和 OpenFeign 都是基于HTTP协议调用远程接口。而 Dubbo Spring Cloud 是基于 TCP 协议来调用远程接口。相比 HTTP 的大量的请求头,TCP 更轻量级。
Dubbo Spring Cloud = Spring Cloud + Dubbo
com.alibaba.cloud
spring-cloud-starter-dubbo
注意:虽然是将 Dubbo 集成到了 Spring Cloud,增加了一些 注解 和 yaml 配置项,开发更方便,但大部分调用玩法还是遵守 Dubbo 框架那一套。
分布式时代,一个复杂的系统被拆分为若干个微服务系统,每个系统都配置独立的域名肯定不合适。为了解决这个问题,网关便诞生了。
网关充当反向代理的角色,作为流量的第一入口,承载了很多基础的、公共的模块功能,如:流控、鉴权、监控、路由转发等。
Spring Cloud 生态早期的网关是 Netflix 公司的Zuul,后来Zuul社区停止了维护。官方后来推出了 Spring Cloud Gateway,其底层是基于 WebFlux 框架,而WebFlux框架的底层采用高性能通讯框架 Netty,性能是 Zuul 的 1.6 倍。
1、路由。
内部主要是负责转发规则。
2、断言(Predicate)
如果返回为true,当前路由才有效,才会路由到具体的服务。官方提供了很多内置路由断言,如果满足不了你的诉求,也可以自定义路由断言工厂。
所有的路由断言工厂都是继承自 AbstractRoutePredicateFactory,自定义类的命名也有固定规则,“配置名”+RoutePredicateFactory。这样,在yaml配置时,只需要写前面定义的配置名即可。
3、过滤器(Filter)
主要是请求、响应之间增加一些自定义的逻辑。按作用范围分为:全局和局部。全局是作用于所有的路由;而局部只是作用于某一个路由。
跟上面的断言类似,除了官方提供的过滤器,也支持自定义。
局部过滤器:继承自 AbstractGatewayFilterFactory,自定义类的命名也有固定规则,“配置名”+GatewayFilterFactory。这样,在yaml配置时,只需要写前面定义的配置名即可。
全局过滤器:实现GlobalFilter,Ordered 两个接口,实现逻辑跟上面的局部过滤器类似。这里就不展开了。其中的 Ordered 接口主要是负责优先级,数值越小,优先级越高。
org.springframework.cloud
spring-cloud-starter-gateway
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+(一个或多个数字)
filters:
- AddRequestHeader=X-Request-token, 12345678 #为原始请求加上请求头及值
当然,服务提供方的地址可能经常变化,为了动态感知,我们引入 Nacos 注册中心,用于服务的注册、发现,统一管理服务的IP地址。网关路由转发时,只需从 Nacos 动态获取即可。
Sentinel 是阿里开源的流控框架,提供了简单易用的控制台,比 Hystrix支持的范围更广。
集成简单,只需要少量配置,即可快速接入,支持如:gRPC、Dubbo、Spring Cloud 等
页面元素介绍:
资源名:唯一即可
针对来源:对调用者限流,填写应用名称(Spring.application.name的值),只针对某个服务限流
阈值类型
流控模式
流控效果
流控规则和降级规则是针对某个资源来说的,而系统规则是针对整个应用的,粒度更大,当前所有的接口服务都会应用这个系统规则。
根据调用方判断调用的接口资源是否被允许,如:黑名单、白名单机制
将粒度进一步细化,可以针对方法的参数做规则控制,为每个参数设置单独的阈值,也可以多个参数组合。从而实现单个方法的热点流量,按业务需求进一步控制。
@SentinelResource 注解可以根据实际情况定制化功能,跟 Hystrix 的 @HystrixCommand 注解功能类似。达到阈值后,系统的默认提示是一段英文,很不友好,所以我们要自定义兜底方法。
// 资源名称为handle1
@RequestMapping("/handle1")
@SentinelResource(value = "handle1", blockHandler = "blockHandlerTestHandler")
public String handle1(String params) {
// 业务逻辑处理
return "success";
}
// 接口方法 handle1 的 兜底方法
public String blockHandlerTestHandler(String params, BlockException blockException) {
return "兜底返回";
}
注意:@SentinelResource注解中,除了blockHandler字段外,还有fallback字段
通过上面两层兜底,可以让Sentinel 框架更加人性化,体验更好。
单机限流很容易做,但是互联网很多应用都是集群部署,毕竟其下游还挂载着 mysql、或者其他微服务,为了防止对下游的大流量冲击,采用集群流控。防止单机的流量不均匀, 理想下 QPS = 单机阈值 * 节点数
事务的原子性和持久性可以确保在一个事务内,更新多条数据,要么都成功,要么都失败。在一个系统内部,我们可以使用数据库事务来保证数据一致性。那如果一笔交易,涉及到跨多个系统、多个数据库的时候,用单一的数据库事务就没办法解决了,此时需要引入分布式事务
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,默认 AT 模式 ,为用户打造一站式的分布式解决方案。
关于 Seata 之前写过很多文章,这里就不展开了,感兴趣可以看看
Spring Cloud Stream 是统一消息中间件编程模型的框架,屏蔽了底层消息中间件的差异。支持的MQ 框架有 RabbitMQ、Kafka、RocketMQ 等
com.alibaba.cloud
spring-cloud-starter-stream-rocketmq
@SpringBootApplication
@EnableBinding({CustomSource.class})
public class StreamProduceApplication {
public static void main(String[] args) {
SpringApplication.run(StreamProduceApplication.class, args);
}
}
public interface CustomSource {
@Output("output1")
MessageChannel output1();
}
spring:
cloud:
stream:
rocketmq:
binder:
name-server: 127.0.0.1:9876 # rocketMq服务地址
bindings:
output1:
producer:
transactional: true # 事务
group: myTxProducerGroup # 事务分组
bindings:
output1:
destination: test-transaction-topic # 主题
content-type: application/json # 数据类型
@Service
public class SendMessageService {
@Resource
private CustomSource customSource;
public String sendMessage() { //发送简单字符串消息的方法
String message = "字符串测试消息";
// 发送消息
customSource.output1().send(MessageBuilder.withPayload(message).build());
return "发送成功!";
}
}
SkyWalking 是 一款 APM(应用性能监控)系统,专为微服务、云原生架构、容器(Docker、k8s、Mesos)而设计。通过探针收集应用的指标,进行分布式链路追踪,感知服务间的调用链路关系。
左部分 SkyWalking UI :负责提供控台,查看链路等等。
SkyWalking 部署起来还是很简单的,apache官网直接下载并解压即可。
https://skywalking.apache.org/
SkyWalking 快速入门手册:
https://skywalking.apache.org/zh/2020-04-19-skywalking-quick-start/
关于定时任务,相信大家都不陌生。但是单节点的定时任务有很多不足:
无论是集群化,还是周边的生态建设,都不完备。而 XXL-JOB,可以完美解决这些问题。
XXL-JOB 是一款分布式任务调度框架,依赖的组件少(仅依赖 Java 和 MySQL),开箱即用。并提供了可视化界面,统计任务数据,动态修改任务执行时间,内置邮件报警,支持任务分片和任务失败重试。
1、调度中心
本身不执行业务逻辑,只负责向执行器发送调度命令。
2、执行器
接收调度中心的请求,并执行业务逻辑。
com.xuxueli
xxl-job-core
2.2.0
server:
port: 8082 #程序端口
xxl:
job:
admin:
addresses: http://127.0.0.1:8002/xxl-job-admin # 调度中心地址,多个用逗号分开
accessToken: # 调度中心和执行器通信的token,如果设置,两边要一样
executor:
appname: xxl-job-executor-sample #执行器名称
address: # 执行器地址,默认使用xxl.job.executor.address配置项,如果为空,则使用xxl.job.executor.ip + xxl.job.executor.port
ip: # 执行器IP
port: 9989 #执行器端口,与调度中心通信的端口
logpath: D:/work/Spring-Cloud-Alibaba/sample/logs # 日志保存路径
logretentiondays: 30 # 日志保留天数
@Bean
public XxlJobSpringExecutor xxlJobExecutor() { // XXL-JOB执行器初始化
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
我们可以采用 BEAN 模式, 使用 @XxlJob 注解描述代码。优点:适用于一些复杂的业务场景。
也可以采用 GLUE 模式,将 执行代码 托管到调度中心在线维护。优点:简单快捷,不需要单独的业务工程。
如果要处理的数据量较大时,我们可以采用分片处理机制,将任务均摊到每个节点,从而减轻单个节点的压力。
shardingVO.getIndex() # 当前执行器的分片序号(从0开始)
shardingVO.getTotal() # 总分片数,执行器集群的数量
# dataSource 待处理的所有原始数据
for (Integer val : dataSource) { // 遍历代理
if (val % shardingVO.getTotal() == shardingVO.getIndex()) { // 取余
//TODO 归属于当前分片处理
}
}
XXL-JOB 快速入门手册:
https://www.xuxueli.com/xxl-job/
巨人肩膀:
《Spring Cloud Alibaba 微服务实战》
网页标题:创业公司就应该技术选型SpringCloudAlibaba,开箱即用
网页链接:http://www.shufengxianlan.com/qtweb/news16/373866.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联