专栏目录
- 1-Spring Cloud Alibaba实战-系统架构演变与微服务常见问题
- 2-Spring Cloud Alibaba实战-简介与组件说明
- 3-Spring Cloud Alibaba实战-全组件项目搭建手册
- 4-Spring Cloud Alibaba实战-服务治理
- 5-Spring Cloud Alibaba实战-Nacos Config–配置中心
- 6-Spring Cloud Alibaba实战-Gateway网关核心架构
- 7-Spring Cloud Alibaba实战-Gateway网关核心原理
- 8-Spring Cloud Alibaba实战-分布式服务治理机制
- 9-Spring Cloud Alibaba实战-Sentinel原理
- 10-Spring Cloud Alibaba实战-Sleuth–链路追踪
- 11-Spring Cloud Alibaba实战-Nacos核心原理
依赖环境搭建
1、安装软件清单
- Jdk1.8 需要配置环境变量,可直接运行java
- Maven 3.2 需要配置环境变量,可直接运行mvn
- Seata-1.3 分布式事务组件
- Nacos-1.2.1 注册配置中心
- MySql 5.7 数据库
2、服务器集群信息
主机名称 | 内网IP |
---|---|
server02 | 192.168.1.101 |
server03 | 192.168.1.102 |
server04 | 192.168.1.103 |
3、 spring-cloud-alibaba组件版本
版本说明:
https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
4、 分布式事务Seata
下载
地址:https://github.com/seata/seata/releases
安装
cd work/SpringCloudAlibaba
# 下载包上传到目录下
#解压
unzip seata-server-1.3.0.zip
#解压后文件夹为 seata
数据库表初始化
初始化业务数据库undo_log表
-- the table to store seata xid data
-- 0.7.0+ add context
-- you must to init this sql for you business databese. the seata server not need it.
-- 此脚本必须初始化在你当前的业务数据库中,用于AT 模式XID记录。与server端无关(注:业务数据库)
-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log
-- drop table `undo_log`;
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
启动服务
# 进入seata/bin目录,执行以下命令启动seata-server
cd seata/bin/
nohup sh seata-server.sh -m file &
5、注册配置中心 nacos
下载
地址 https://github.com/alibaba/nacos/releases
安装
cd work/SpringCloudAlibaba
# 下载包上传到目录下
#解压
unzip nacos-server-1.2.1.zip
#解压后文件夹为 nacos
数据库初始化
创建数据库nacos
CREATE DATABASE IF NOT EXISTS nacos CHARACTER SET utf8;
创建表
表结构文件在nacos/conf/nacos-mysql.sql
执行以下语句
use nacos;
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_info */
/******************************************/
CREATE TABLE `config_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(255) DEFAULT NULL,
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COMMENT 'source user',
`src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip',
`app_name` varchar(128) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
`c_desc` varchar(256) DEFAULT NULL,
`c_use` varchar(64) DEFAULT NULL,
`effect` varchar(64) DEFAULT NULL,
`type` varchar(64) DEFAULT NULL,
`c_schema` text,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_info_aggr */
/******************************************/
CREATE TABLE `config_info_aggr` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(255) NOT NULL COMMENT 'group_id',
`datum_id` varchar(255) NOT NULL COMMENT 'datum_id',
`content` longtext NOT NULL COMMENT '内容',
`gmt_modified` datetime NOT NULL COMMENT '修改时间',
`app_name` varchar(128) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_info_beta */
/******************************************/
CREATE TABLE `config_info_beta` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL COMMENT 'content',
`beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COMMENT 'source user',
`src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip',
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_info_tag */
/******************************************/
CREATE TABLE `config_info_tag` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
`tag_id` varchar(128) NOT NULL COMMENT 'tag_id',
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COMMENT 'source user',
`src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_tags_relation */
/******************************************/
CREATE TABLE `config_tags_relation` (
`id` bigint(20) NOT NULL COMMENT 'id',
`tag_name` varchar(128) NOT NULL COMMENT 'tag_name',
`tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
`nid` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`nid`),
UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = group_capacity */
/******************************************/
CREATE TABLE `group_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = his_config_info */
/******************************************/
CREATE TABLE `his_config_info` (
`id` bigint(64) unsigned NOT NULL,
`nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`data_id` varchar(255) NOT NULL,
`group_id` varchar(128) NOT NULL,
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL,
`md5` varchar(32) DEFAULT NULL,
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`src_user` text,
`src_ip` varchar(20) DEFAULT NULL,
`op_type` char(10) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
PRIMARY KEY (`nid`),
KEY `idx_gmt_create` (`gmt_create`),
KEY `idx_gmt_modified` (`gmt_modified`),
KEY `idx_did` (`data_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = tenant_capacity */
/******************************************/
CREATE TABLE `tenant_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';
CREATE TABLE `tenant_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`kp` varchar(128) NOT NULL COMMENT 'kp',
`tenant_id` varchar(128) default '' COMMENT 'tenant_id',
`tenant_name` varchar(128) default '' COMMENT 'tenant_name',
`tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc',
`create_source` varchar(32) DEFAULT NULL COMMENT 'create_source',
`gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
`gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';
CREATE TABLE `users` (
`username` varchar(50) NOT NULL PRIMARY KEY,
`password` varchar(500) NOT NULL,
`enabled` boolean NOT NULL
);
CREATE TABLE `roles` (
`username` varchar(50) NOT NULL,
`role` varchar(50) NOT NULL,
UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
);
CREATE TABLE `permissions` (
`role` varchar(50) NOT NULL,
`resource` varchar(512) NOT NULL,
`action` varchar(8) NOT NULL,
UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
);
INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');
修改配置
修改原有配置为当前配置
spring.datasource.platform=mysql
### Count of DB:
db.num=1
# 注意以下的数据库连接、用户名、密码,请配置正确
# 注意以下的数据库连接、用户名、密码,请配置正确
# 注意以下的数据库连接、用户名、密码,请配置正确
### Connect URL of DB:
db.url.0=jdbc:mysql://IP:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=user
db.password=password
启动
cd nacos/bin
sh startup.sh -m standalone
访问nacos
http://127.0.0.1:8848/nacos/#/login
默认账号 nacos
密码 nacos
常用命令
cd nacos/bin
# 启动服务
sh startup.sh -m standalone
# 关闭服务
sh shutdown.sh
# 查看log
tail -f ../logs/nacos.log
6、服务流控 Sentinel
启动控制台
获取 Sentinel 控制台
您可以从 release 页面 下载最新版本的控制台 jar 包。
您也可以从最新版本的源码自行构建 Sentinel 控制台:
- 下载 控制台 工程
- 使用以下命令将代码打包成一个 fat jar:
mvn clean package
启动
注意:启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。
使用如下命令启动控制台:
java -Dserver.port=8888 -Dcsp.sentinel.dashboard.server=localhost:8888 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.0.jar
其中 -Dserver.port=8888
用于指定 Sentinel 控制台端口为 8888
。
从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 sentinel
。
客户端接入控制台
控制台启动后,客户端需要按照以下步骤接入到控制台。
引入JAR包
客户端需要引入 Transport 模块来与 Sentinel 控制台进行通信。您可以通过 pom.xml
引入 JAR 包:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<exclusions>
<exclusion>
<artifactId>jackson-dataformat-xml</artifactId>
<groupId>com.fasterxml.jackson.dataformat</groupId>
</exclusion>
</exclusions>
</dependency>
客户端配置参数
在bootstrap.yml中配置
spring:
cloud:
sentinel:
transport:
clientIp: localhost
dashboard: localhost:9090 #sentinel 监控端口,定义一个未使用的端口极客
port: 8888 # sentinel运行端口
配置启动参数
启动时加入 JVM 参数 -Dcsp.sentinel.dashboard.server=localhost:8888
指定控制台地址和端口。
项目架构说明
1、项目结构说明
- common
项目公用模块(实体类,Dubbo Api等)
- customer
服务消费者
- provider
服务提供者
- gateway
网关
2、部署运行流程
- 通过svn下载代码
- 项目打包,各模块成为 jar
- 运行服务注册中心nacos
- 运行seata事务组件
- 运行provider服务
- 运行customer服务
- 运行gateway
3、部署步骤
3.1、下载代码
详细说明略
3.2、项目打包
对项目springcloud-alibaba打包
# 进入下载的源码根目录
cd springcloud-alibaba
mvn package
打包完成后,将得到三个可运行jar
customer 所在路径springcloud-alibaba/customer/target/customer-0.0.1-SNAPSHOT.jar
provider 所在路径springcloud-alibaba/provider/target/provider-0.0.1-SNAPSHOT.jar
gateway 所在路径springcloud-alibaba/gateway/target/gateway-0.0.1-SNAPSHOT.jar
3.3、 服务器服务配置表
主机名称 | 运行服务 | jar | 服务器路径 | 运行端口 |
---|---|---|---|---|
server02 | nacos | - | /home/nacos | 8848 |
server02 | seata | - | /home/seata | 8091 |
server02 | gateway | gateway-0.0.1-SNAPSHOT.jar | /home/server/jar/gateway | 8080 |
server03 | customer | customer-0.0.1-SNAPSHOT.jar | /home/server/jar/customer | 18081 |
server03 | provider | provider-0.0.1-SNAPSHOT.jar | /home/server/jar/provider | 18080 |
server04 | customer | customer-0.0.1-SNAPSHOT.jar | /home/server/jar/customer | 18081 |
server04 | provider | provider-0.0.1-SNAPSHOT.jar | /home/server/jar/provider | 18080 |
3.4、运行provider服务
在server03运行服务
# 运行provider service1
# 使用nohup命令以后台进程运行
cd /home/kojon/jar/provider
nohup java -jar provider-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod --logging.file.path=/home/kojon/logs --spring.cloud.nacos.discovery.server-addr=39.106.248.143:8848 --seata.service.grouplist.default=39.106.248.143:8091 --csp.sentinel.dashboard.server=localhost:8888 &
# 查看运行log
tail -f /home/kojon/logs/provider.log
在server04运行服务
# 运行provider service2
# 使用nohup命令以后台进程运行
cd /home/kojon/jar/provider
nohup java -jar provider-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod --logging.file.path=/home/kojon/logs --spring.cloud.nacos.discovery.server-addr=39.106.248.143:8848 --seata.service.grouplist.default=39.106.248.143:8091 --csp.sentinel.dashboard.server=localhost:8888 &
# 查看运行log
tail -f /home/kojon/logs/provider.log
3.5、运行customer服务
在server03运行服务
# 运行customer service1
# 使用nohup命令以后台进程运行
cd /home/kojon/jar/customer
nohup java -jar customer-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod --logging.file.path=/home/kojon/logs --spring.cloud.nacos.server-addr=39.106.248.143:8848 --seata.service.grouplist.default=39.106.248.143:8091 --csp.sentinel.dashboard.server=localhost:8888 &
# 查看运行log
tail -f /home/kojon/logs/customer.log
在server04运行服务
# 运行customer service2
# 使用nohup命令以后台进程运行
cd /home/kojon/jar/customer
nohup java -jar customer-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod --logging.file.path=/home/kojon/logs --spring.cloud.nacos.server-addr=39.106.248.143:8848 --seata.service.grouplist.default=39.106.248.143:8091 --csp.sentinel.dashboard.server=localhost:8888 &
# 查看运行log
tail -f /home/kojon/logs/customer.log
3.6、运行gateway服务
在server02运行服务
# 运行gateway
# 使用nohup命令以后台进程运行
cd /home/kojon/jar/gateway
nohup java -jar gateway-0.0.1-SNAPSHOT.jar --spring.cloud.nacos.server-addr=39.106.248.143:8848 > /home/kojon/logs/gateway.log --csp.sentinel.dashboard.server=localhost:8888 &
# 查看运行log
tail -f /home/kojon/logs/gateway.log
4、请求接口
浏览器访问 http://127.0.0.1:8080/user/select?userId=43
可正常返回结果
项目运行流程
服务端启动和请求交互流程
- provider向nacos注册中心注册服务
- customer向nacos注册中心订阅provider的服务,
- nacos通知customer,customer获得了provider的服务信息
- 客户端发起请求到gateway网关服务
- gateway转发请求到customer
- customer调用provider
- customer返回数据到gateway
- 响应结果到客户端
开发说明
代码编写过程
- 代码生成
-
配置文件在 springcloud-alibaba/provider/src/main/resources/codeGenerator/generatorConfig.xml
-
执行maven-mybatis-generator
-
讲生成的db实体类放到common的domain包下
springcloud-alibaba/common/src/main/java/com/sunwebstar/common/domain
-
在common的com.sunwebstar.common.dubbo.api下编写service
-
在provider的com.sunwebstar.provider.dubbo下编写service实现类,实现数据逻辑层
-
在provider的com.sunwebstar.provider.controller下编写feign实现类(被调用者),调用service实现类完成业务逻辑
-
在customer的com.sunwebstar.customer.feign下编写feign抽象类(调用者),Mapping路径需要与feign实现类匹配
-
在customer的com.sunwebstar.customer.controller下编写API接口,调用feign抽象类