SpringCloudTencent
- 1.PolarisMesh介绍
- 2.北极星具备的功能
- 3.北极星包含的组件
- 4.功能特性
- 1.服务管理
- 1.服务注册
- 2.服务发现
- 3.健康检查
- 2.配置管理
- 5.代码实战
- 1.环境准备
- 2.服务注册与发现
- 3.远程调用
1.PolarisMesh介绍
1.北极星是腾讯开源的服务治理平台,致力于解决分布式和微服务架构中的服务管理、流量管理、配置管理、故障容错和可观测性问题,针对不同的技术栈和环境提供服务治理的标准方案和最佳实践
2.官方文档:https://polarismesh.cn/docs
3.项目地址:https://github.com/PolarisMesh
4.在线体验:http://119.91.66.223/#/login
- 用户名:polaris
- 密码:polaris
2.北极星具备的功能
1.结构图
2.北极星具备服务管理、流量管理、故障容错、配置管理和可观测性五大功能:
- 服务管理:包含服务发现、服务注册、健康检查和元数据管理。
- 服务发现:支持 HTTP、SDK 和 DNS 服务发现方式。
- 服务注册:支持 HTTP、SDK、控制台操作和 K8s 服务注册方式。
- 健康检查:支持服务实例上报心跳,通过心跳判断实例是否健康,及时剔除异常实例。
- 元数据管理:支持在服务和实例上配置协议、版本和位置等标签,实现动态路由等功能。
- 流量管理:包含动态路由、负载均衡和访问限流。
- 动态路由:支持自定义路由策略,将服务的部分请求路由到部分实例,用于灰度发布等应用场景。
- 负载均衡:支持权重轮训、权重随机和权重一致性 Hash 等负载均衡算法。
- 访问限流:支持本地和分布式两种模式,被限流的请求支持排队和自定义响应。
- 故障容错:包含服务熔断和节点熔断。
- 服务熔断:对服务或者接口进行熔断,如果服务或者接口发生熔断,返回自定义响应。
- 节点熔断:对服务实例进行熔断,不会将请求路由到熔断的服务实例,降低请求失败率。
- 主动探测:服务和节点熔断除了被动探测,还支持主动探测,进一步降低请求失败率。
配置管理:包含配置变更、配置校验、版本管理和灰度发布等功能。
- 可观测性:提供业务流量、系统事件和操作记录等监控视图。
3.北极星包含的组件
1.结构图
2.北极星的系统组件分为控制台、控制面和数据面三个部分
- 控制台:提供简单易用的管理页面,支持用户和权限管理。
- 控制面:包含核心组件 Polaris 和可选的功能组件,核心组件可以满足绝大部分业务需求,可选的功能组件按需部署。
- 数据面:提供多语言 SDK、开发框架、Java Agent 和网格代理四种形态的实现,满足不同的业务场景和开发模式,支持异构服务的互联互通和统一治理。
3.控制面组件
-
Polaris:支持各种形态的数据面接入,支持服务和配置数据的管理和下发,支持流量管理和熔断降级策略的管理和下发,可以覆盖服务注册中心、服务网格控制面和配置中心的功能。
-
Polaris Controller:可选的功能组件,支持 K8s 服务同步和网格代理注入。K8s 服务同步将 K8s 服务按需同步到北极星,用户不需要在应用程序里显式地注册服务。网格代理注入按需在应用程序 Pod 里注入北极星 Sidecar,以流量代理的方式实现服务发现和治理功能。
4.数据面组件
-
SDK:北极星提供轻量级的多语言 SDK,使用方法和绝大部分客户端软件类似,用户在应用程序里引入北极星 SDK。这种数据面形态以无流量代理的方式实现服务发现和治理功能,没有额外的性能和资源损耗,不会增加现网运维和问题定位的成本。
-
开发框架:北极星 SDK 可以被集成到开发框架内部,如果用户使用开发框架,不需要显式地引入北极星 SDK。对于 Spring Cloud、Dubbo 和 gRPC 等开发框架,北极星提供可以无缝集成的依赖包。另外,go-micro、go-kratos、go-zero、GoFrame 和 CloudWeGo 等开发框架社区也提供北极星插件。
-
Java Agent:对于 Spring Cloud 和 Dubbo 等 Java 开发框架,北极星支持 Java 生态常用的 Agent 接入模式。用户只需要在应用程序的启动命令中引入 Polaris Java Agent,即可将北极星的服务发现和治理功能引入应用程序,不需要改动任何代码和配置文件。
-
网格代理:北极星网格代理在应用程序 Pod 里注入 Polaris Sidecar 和 Proxy,前者通过劫持 DNS 解析将请求转到后者,后者通过流量代理实现服务发现和治理功能。这种数据面形态适合性能和资源损耗不敏感的业务,要求业务具备网格代理的运维能力
4.功能特性
1.服务管理
1.服务注册
服务注册指的是被调方按照服务模型将自身的服务数据注册到北极星,以供主调方进行服务发现。(这里和我们常用的nacos差不多)
1.服务数据主要包括以下部分:
- 服务名:服务的唯一标识,区分大小写。
- 服务元数据:服务的标签信息,KV格式,可对服务进行分类,可用于过滤。
- 服务实例:提供服务的节点列表,以IP:PORT的方式提供。
- 服务实例元数据:服务实例的标签信息,KV格式,通常用于描述节点的集群、版本等,用于后续 流量治理等操作。
2.服务注册的方式
3.通过SDK注册:北极星提供了多语言SDK,服务可以通过集成SDK,调用registerInstance接口完成服务注册
4.通过服务框架注册
- 服务框架会提供通用的服务注册接口,供应用在拉起的时候,自动往注册中心注册
- 北极星对主流的服务框架(SpringCloud,Dubbo,gRPC)做了适配,用户无需修改业务逻辑代码,只需引入北极星的框架扩展库,即可实现自动注册
5.通过k8s同步的方式注册:用户通过k8s部署服务,并注册为k8s的service,北极星通过controller的机制,从k8s中将service和endpoint信息同步到北极星,完成服务注册
6.通过OpenAPI注册:北极星控制面提供基于Rest标准的OpenAPI,用户可通过OpenAPI完成服务注册的操作
2.服务发现
服务发现指的主调方是根据服务名标识,拉取服务实例列表,以供后续进行服务调用的操作
1.服务发现的方式
2.通过SDK进行服务发现
- 北极星提供了多语言SDK,SDK通过ConsumerAPI提供3个接口进行服务发现:
- getAllInstances:获取服务下全量的服务实例列表,不做任何过滤。
- getHealthyInstances:获取服务下健康的服务实例列表,只包含健康实例,不包含被熔断、不健康、隔离、权重为0的实例。
- getOneInstances:针对健康的服务实例列表,进行动态路由和负载均衡,返回单个可用的服务实例。
3.通过服务框架进行服务发现
- 服务框架会提供通用的服务发现接口,应用在RPC之前,会自动进行服务发现,获取到可用的实例进行RPC调用
- 北极星对主流的服务框架(SpringCloud,Dubbo,gRPC)做了适配,用户无需修改业务逻辑代码,只需引入北极星的框架扩展库,即可实现自动发现
4.使用DNS进行服务发现:北极星通过polaris-sidecar提供DNS功能,用户程序可以通过DNS域名访问的方式,实现无侵入的服务发现
5.使用OpenAPI服务发现:北极星控制面提供基于Rest标准的OpenAPI,用户可通过OpenAPI完成服务发现的操作
3.健康检查
健康检查提供了一种机制,使得控制面可以在一定时间段内,感知服务实例出现异常,从而将异常节点剔除,并通知给所有的消费者
心跳上报:服务实例持续上报心跳给控制面,并与控制面约定TTL的时间段,控制面检查服务实例的心跳上报时间点,当发现当前时间相比实例最后一次上报时间已经超过3*TTL,就将实例标记为不健康,并通知给该服务的消费者
2.配置管理
1.结构图
2.客户端视角
- 应用启动时,同步从服务端拉取一次配置,获取最新的配置内容
- 把第一步拉取到的所有的配置文件生成 ListVersion> 的数据 ,并向服务端发送订阅配置请求,请求内容为 ListVersion>
- 当收到配置文件的推送消息时,向服务端拉取最新的配置文件
3.配置服务端视角
- 先检查客户端 ListVersion> 的请求里是否存在 File 版本号落后,如果存在,则立马响应 File -> NewVersion 内容给客户端
- 如果客户端配置文件版本号都是最新的,则在内存里维护 File -> List 的数据结构并 Hold 请求 30s。如果 30s 内有配置文件发布,则立马响应请求,返回 File -> NewVersion 给所有客户端.
4.发布推送配置简化流程
- 用户在界面点击发布按钮,服务端更新数据库里配置发布表的数据。配置发布表的核心字段:file, version, content, mtime
- 每个北极星服务端实例,都会定时1s扫描配置发布表,根据 mtime 捞出最近 1s 内变更过的数据
- 北极星服务端实例扫描到最新变更的数据之后
- 重新加载内存缓存.
- 向内存里的消息发布管道里写入一条消息
- 推送协程从消息发布管道里获取到消息,并消费消息。通过 File -> List 信息,获取所有订阅配置文件的客户端信息,并响应客户端 Hold 的请求
5.代码实战
1.环境准备
1.PolarisMesh安装方式可以看我之前的博客:polarismesh安装
2.版本对照表地址: 版本对照
Spring Cloud Tencent 版本 | 支持 Spring Boot 版本 | Spring Cloud 版本 | Spring Boot 版本 Spring Framework 版本 |
---|---|---|---|
1.12.4-2022.0.4(推荐) | >=3.0.0 | 2022.0.4 3.1.2 | 6.0.11 |
1.11.9-2022.0.1 | >=3.0.0 | 2022.0.1 3.0.4 | 6.0.7 |
1.10.3-2022.0.1 | >=3.0.0 | 2022.0.1 3.0.4 | 6.0.7 |
1.9.0-2022.0.1 | >=3.0.0 | 2022.0.1 3.0.2 | 6.0.4 |
1.8.5-2022.0.1 | >=3.0.0 | 2022.0.1 3.0.2 | 6.0.4 |
3.老规矩创建一个微服务项目
注意:博主采用的是最新版jdk21和SpringBoot3实现的
springBoot3_jdk21_tencent ------------------- 父工程
├── t_server_address ------------------------- 提供者
├── t_server_user ------------------------------ 消费者
├── t_openFeign_api -------------------------- Feign接口
t_server_address工程的sql:
下面的sql是一对多关系,一个用户有多个地址
CREATE TABLE `address` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`user_id` bigint(20) NULL DEFAULT NULL COMMENT '用户ID',`province` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '省',`city` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '市',`town` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '县/区',`mobile` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '手机',`street` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '详细地址',`contact` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系人',`is_default` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '是否是默认 1默认 0否',`notes` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注',PRIMARY KEY (`id`) USING BTREE,INDEX `user_id`(`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 64 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;INSERT INTO `address` VALUES (59, 1, '北京', '北京', '朝阳区', '13900112222', '金燕龙办公楼', '李嘉诚', '0', NULL);
INSERT INTO `address` VALUES (60, 1, '北京', '北京', '朝阳区', '13700221122', '修正大厦', '李佳红', '0', NULL);
INSERT INTO `address` VALUES (61, 2, '上海', '上海', '浦东新区', '13301212233', '航头镇航头路', '李佳星', '1', NULL);
INSERT INTO `address` VALUES (63, 3, '广东', '佛山', '永春', '13301212233', '永春武馆', '李小龙', '0', NULL);
SET FOREIGN_KEY_CHECKS = 1;
t_server_user工程的sql
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',`password` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码,加密存储',`phone` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '注册手机号',`create_time` datetime NOT NULL COMMENT '创建时间',`update_time` datetime NOT NULL,`status` int(11) NULL DEFAULT 1 COMMENT '使用状态(1正常 2冻结)',`balance` int(11) NULL DEFAULT NULL COMMENT '账户余额',PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;
INSERT INTO `user` VALUES (1, 'Jack', '123456', '13900112224', '2017-08-19 20:50:21', '2017-08-19 20:50:21', 1, 838500);
INSERT INTO `user` VALUES (2, 'Rose', '123456', '13900112223', '2017-08-19 21:00:23', '2017-08-19 21:00:23', 1, 1000000);
INSERT INTO `user` VALUES (3, 'Hope', '123456', '13900112222', '2017-08-19 22:37:44', '2017-08-19 22:37:44', 1, 1000000);
INSERT INTO `user` VALUES (4, 'Thomas', '123456', '17701265258', '2017-08-19 23:44:45', '2017-08-19 23:44:45', 1, 1000000);
SET FOREIGN_KEY_CHECKS = 1;
3.所有工程的坐标
父工程
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.andy</groupId><artifactId>springBoot3_jdk21_tencent</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><modules><module>t_server_user</module><module>t_server_address</module><module>t_openFeign_api</module></modules><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.2</version><relativePath/></parent><properties><maven.compiler.source>21</maven.compiler.source><maven.compiler.target>21</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring-cloud.version>2022.0.0</spring-cloud.version><spring-cloud-tencent.version>1.12.3-2022.0.4</spring-cloud-tencent.version></properties><dependencyManagement><!--rest--><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-rest</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency><!--spring-cloud--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><!--spring-cloud-tencent--><dependency><groupId>com.tencent.cloud</groupId><artifactId>spring-cloud-tencent-dependencies</artifactId><version>${spring-cloud-tencent.version}</version><type>pom</type><scope>import</scope></dependency><!--spring-cloud-tencent所有的模块--><dependency><groupId>com.tencent.cloud</groupId><artifactId>spring-cloud-starter-tencent-all</artifactId></dependency></dependencies></dependencyManagement>
</project>
t_server_user工程
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.andy</groupId><artifactId>springBoot3_jdk21_tencent</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>t_server_user</artifactId><properties><maven.compiler.source>21</maven.compiler.source><maven.compiler.target>21</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- springboot数据基本 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-rest</artifactId><version>3.1.2</version></dependency><!-- mysql 与安装的版本要相同 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.32</version></dependency><!-- fastjson2 --><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.35</version></dependency><!-- mybatis-plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version></dependency><!-- tencent所有依赖 --><dependency><groupId>com.tencent.cloud</groupId><artifactId>spring-cloud-starter-tencent-all</artifactId><version>1.12.3-2022.0.4</version></dependency><!-- bootstrap --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId><version>3.1.2</version></dependency><!-- openFeign_api --><dependency><groupId>com.andy</groupId><artifactId>t_openFeign_api</artifactId><version>1.0-SNAPSHOT</version></dependency><!-- loadbalancer --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-loadbalancer</artifactId></dependency></dependencies></project>
t_server_address工程
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.andy</groupId><artifactId>springBoot3_jdk21_tencent</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>t_server_address</artifactId><properties><maven.compiler.source>21</maven.compiler.source><maven.compiler.target>21</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- springboot数据基本 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-rest</artifactId><version>3.1.2</version></dependency><!-- mysql 与安装的版本要相同 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.32</version></dependency><!-- fastjson2 --><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.35</version></dependency><!-- mybatis-plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version></dependency><!-- druid连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.16</version></dependency><!-- tencent所有依赖 --><dependency><groupId>com.tencent.cloud</groupId><artifactId>spring-cloud-starter-tencent-all</artifactId><version>1.12.3-2022.0.4</version></dependency><!-- bootstrap --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId><version>3.1.2</version></dependency></dependencies>
</project>
t_openFeign_api工程
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.andy</groupId><artifactId>springBoot3_jdk21_tencent</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>t_openFeign_api</artifactId><properties><maven.compiler.source>21</maven.compiler.source><maven.compiler.target>21</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--Open feign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency></dependencies></project>
2.服务注册与发现
1.关于pojo,mapper,service和controler层的代码省略。这4层的代码我相信给位大佬在学习nacos或者用springBoot集成mybatis-plus都搭建过,并且比博主玩的更溜。博主在这里只写application层和配置文件bootstrap.yml
- t_server_user的配置文件
server:port: 18081
spring:application:name: t-user #注意这里的服务名称不要写下滑线,要不然openFeign会报错的cloud:polaris:address: grpc://192.168.6.210:8091 # PolarisMesh的连接namespace: andy_namespace # 命名空间,和nacos的namespace一样 config:namespace: andy_namespacegroups: # 组- name: t_user # 配置文件在哪个组中files: ["application.yml"] # 配件文件 这里是数组,如果配置中心有多个用逗号分开
友情提示:
- t_server_addressr的配置文件
server:port: 18080
spring:application:name: t-addresscloud:polaris:address: grpc://192.168.6.210:8091namespace: andy_namespaceconfig:auto-refresh: truegroups:- name: t_userfiles: ["application.yml"]
2.编写t_server_address和t_server_user的启动类
t_server_address工程
@SpringBootApplication
@EnableDiscoveryClient
public class AddressApplication {public static void main(String[] args) {SpringApplication.run(AddressApplication.class, args);}
}
t_server_user工程
@SpringBootApplication
@EnableDiscoveryClient
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class, args);}
}
3.在PolarisMesh创建配置文件
- 创建一个命名空间
-
新建配置组
-
点击t_user进入
-
点击新增后在配置文件名中数据我们在bootstrap.yml文件配置的文件名,并且提交
-
点击配置文件名称后,再次点击编辑
-
输入数据库配置后点击保存
-
最后点击发布,输入版本号,一路下一步就可以了
4.启动项目,验证是否注册成功
3.远程调用
1.坐标我们在环境准备中有导入了
2.在t-server_user项目中编写Feign接口:
@FeignClient(value = "t-address")
public interface AddressApi {@RequestMapping("/address/findByUserId/{id}")List<Address> findByUserId(@PathVariable("id")Long id);
}
3.在service层调用
@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Resourceprivate UserMapper userMapper;@Resourceprivate AddressApi addressApi;@Overridepublic User findById(Long id) {User user = userMapper.selectById(id);List<Address> byUserId = addressApi.findByUserId(user.getId());user.setUserList(byUserId);return user;}
}
4.在t_server_user项目的启动类上添加注解
@EnableFeignClients(basePackages = "com.andy.tencent.cloud.feign")
t_server_user项目的启动类完整代码
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.andy.tencent.cloud.feign")
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class, args);}
}
5.启动项目测试