# shy-cloud
**Repository Path**: wangyuhangde/shy-cloud
## Basic Information
- **Project Name**: shy-cloud
- **Description**: 一套完整的微服务架构体系
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2024-03-06
- **Last Updated**: 2024-10-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# spring-cloud-demo
## service-luna
* 业务代码:http://localhost:8763/hi?name=forezp
* 功能:
* 使用nacos作为服务注册中心和配置中心
* 使用elasticsearch
* 启动命令添加skywalking探针,java -javaagent:x:\xxx\skywalking-agent\skywalking-agent.jar --SW_AGENT_NAME=应用名(必须英文) -jar your_application.jar
注意:8.5.0 加上--SW_AGENT_NAME设置服务名,否则会使用skywalking的默认值
* druid监控,相关配置在com.demo.config.servlet,监控url:http://localhost:8763/druid/login.html
根据方法返回值将纯JSON格式字符串反序列化相应对象
* Junit注解使用JunitAnnotaionTest.java
* controller目录下功能
* ValidateController 校验请求参数
* SkywalkingController 配合skywalking功能调试
* RequestHeaderController 请求头某个属性值JSON转换成对象
* function目录下是介绍Java和第三方jar包的使用
* 算法
* Kafka 时间轮算法
* 快速排序算法
* 日志对接graylog
* retrofit http客户端使用
* Java线程相关测试
* 使用shardingsphere实现分库规则 (搭建shardingsphere proxy服务,可以将分库聚合成一个库,通过工具方便查询)
* 分片策略所在的路径 com.demo.function.shardingsphere.config
* 强制分片AOP com.demo.function.shardingsphere.aop.ShardingStrageyAop
* 强制分片注解 com.demo.function.shardingsphere.annotation.ShardingStrategy
* spring功能使用
* WebFlux提供WebClient
* OpenFeign拦截
* Loadbalancer灰度负载均衡器,被调用的服务需要走灰度,在nacos的元数据添加gray: true
* 类:
* com.demo.config.GrayLoadBalancerConfig (自定义)
* com.demo.config.SpringHintLoadBalancerConfiguration (Spring Loadbalancer提供)
* 注意:使用延迟初始化,只需要启动以下服务:
* nacos
* elasticsearch
## service-cache
* 主要缓存功能模块功能介绍
* 功能:
* redis使用
* 实现注解方式添加锁,底层使用redisson加锁和释放锁
* redisson加锁
* redisTemplate批量添加数据测试
* SpringBoot Cache使用
* 使用spring cache,缓存实现方案用到redis。并且增加注解实现失效时间,配置类:RedisConfig。自定义RedisCacheManager,
* caffeine
* caffeine的Cache,LoadingCache,AsyncCache使用
## service-job
* 主要调度任务模块功能介绍
* 功能:
* xxl-job
* ElasticJob-lite
## service-mq
* 主要是mq功能模块功能介绍
* 功能:
* RocketMQ使用
* 常规功能使用
* 自定义时间延时队列,不受原来的18个延时Level限制
* 设计思路:
* 定义proxy-topic,将发送自定义时间的延时消息统一发送到proxy-topic
* 将自定义时间计算不同对应18个延时Level
* 消费者接收延时消息后减去已在延时队列里的时间,重新计算对应的延时Level,再次投入proxy-topic,直到延时时间等于0直接发送到实际的topic
* 类:
* DelayProducer 延时消息生产者
* RocketMQConfig 处理延时消息消费者
* 使用RocketMQ订阅canal得到的数据库日志解析
* 自定义注解@MqConsumer,该注解是方法级别使用。该注解具备@RocketMQMessageListener是一样功能,而且不用为每个主题定义一个类
* 消息自动重发,确保消费端能把消息消费成功
* 设计思路:
* 生产者发送消息时,把回调key和回调tag设置在message的properties,随消息一起发送
* 消费者定义回调主题,消费成功根据回调主题发送消息,消息体和tag从消息的properties获取回调key和回调tag
* 生产者定义一个消费者消费回调消息,更新表flag者
* 定时任务扫描表flag=0 and retry_num < 5的数据,重新发送
* 类:
* RocketCallbackConfig 定义消费者处理回调消息和生产者重新发消息
* RocketMqConfigPropertites 处理回调消息的消费者配置
* ServiceSharding 根据nacos获取服务实例数量再计算机器的分片值,根据分片获取指定重发数据再次重发消息
* 流程图:

* Kafka使用
* 实现延时消息
* 设计思路:
* 定义proxy-topic,将发送自定义时间的延时消息统一发送到proxy-topic
* 设置18个主题proxy-topic,定义每个主题对应不同延时Level
* 将自定义时间计算不同对应18个延时Level,然后将消息投入到指定主题
* 通过时间轮获取主题消息是否到达发送时间
* 消费者接收消息后计算消息发送时间 + 延迟时间是否大于当前时间。
* 大于等于当前时间,立即投递消息到指定topic
* 小于当前时间,不消费消息,等待下一次消费
* 类:
* KafkaDelayProducer 延时消息生产者
* KafkaConsumeDelayMsgConfig 处理延迟消息配置类
* KafkaDelayMsgProcessor 延迟消息处理类
* KafkaTimerTaskProcessor 延迟消息定时任务处理类
## service-miya
* 注意:使用延e迟初始化启动服务,无法消费rocktmq的消息
* 功能:
* 新增rocketmq 消费端,包路径:com.demo.miya.mq.rocketmq。如果消费端没有接收消息,检查配置文件是否开启延迟初始化。
## service-gateway
* 使用springcloud gateway作为网管,实现统一路由方式
* 功能:
* 自定义filter,实现解释token后,将uid赋值到body对象里
* 接入阿里Sentinel实现网关流控,配合Sentinel-dashboard使用时,启动命令必须添加启动参数Dcsp.sentinel.app.type=1,这样才能sentinel dashboard显示网关api分组配置
* 新服务上线自动添加路由规则,实现功能在com.example.servicegateway.route.rule
* 流程图:

* 灰度负载均衡器,实现全链路灰度调用
* 类:
* com.example.servicegateway.config.GrayLoadBalancerConfig (自定义)
* com.example.servicegateway.config.SpringHintLoadBalancerConfiguration (Spring Loadbalancer提供)
## graylog 日志系统
* Graylog 是一个开源的日志聚合、分析、审计、展现和预警工具。对于功能上来说,和 ELK 类似,但又比 ELK 要简单很多。依靠着更加简洁,高效,部署使用简单的优势很快受到许多人的青睐。当然,在扩展性上面确实没有比 ELK 好,但是其有商业版本可以选择
* 容器部署:
* 下载镜像:
* docker pull mongo:4
* docker pull elasticsearch:7.12.1
* docker pull graylog/graylog:4.0
* 启动容器:
* docker run --name mongo -d mongo:4
* docker run --name elasticsearch -e "http.host=0.0.0.0" -e "discovery.type=single-node" -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" -e http.cors.allow-origin="*" -e http.cors.enabled=true -d -p 9200:9200 elasticsearch:7.12.1
* docker run --name graylog --link mongo --link elasticsearch -p 9000:9000 -p 12201:12201/udp -p 1514:1514 -p 5555:5555/udp -e GRAYLOG_HTTP_EXTERNAL_URI="http://127.0.0.1:9000/" -e GRAYLOG_ROOT_TIMEZONE="Asia/Shanghai" -d graylog/graylog:4.0
* graylog email配置
* docker run --name graylog --link mongo --link elasticsearch -p 9000:9000 -p 12201:12201/udp -p 1514:1514 -p 5555:5555/udp -e GRAYLOG_HTTP_EXTERNAL_URI="http://127.0.0.1:9000/" -e GRAYLOG_ROOT_TIMEZONE="Asia/Shanghai" -e GRAYLOG_TRANSPORT_EMAIL_ENABLED=true -e GRAYLOG_TRANSPORT_EMAIL_HOSTNAME=mail.example.com -e GRAYLOG_TRANSPORT_EMAIL_PORT=587 -e GRAYLOG_TRANSPORT_EMAIL_USE_AUTH=true -e GRAYLOG_TRANSPORT_EMAIL_USE_TLS=true -e GRAYLOG_TRANSPORT_EMAIL_AUTH_USERNAME=you@example.com -e GRAYLOG_TRANSPORT_EMAIL_AUTH_PASSWORD=密码 -d graylog/graylog:4.0
* graylog端口9000,1514是使用TCP协议,端口12201,5555是使用UDP协议
* 参考文档:
* [Installing Graylog » Docker](https://docs.graylog.org/en/3.3/pages/installation/docker.html)
* [docker部署graylog使用教程](https://www.cnblogs.com/jonnyan/p/12566994.html)
## skywalking
* SkyWalking 是观察性分析平台和应用性能管理系统。提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案
* 部署:在bin目录下执行startup.bat或startup.sh即可启动服务,执行startup.bat之后会启动如下两个服务
* Skywalking-Collector:追踪信息收集器,通过 gRPC/Http 收集客户端的采集信息 ,Http默认端口 12800,gRPC默认端口 11800。
* Skywalking-Webapp:管理平台页面 默认端口 8080,登录信息 admin/admin
* skywalking所在目录名称不能有空格
* Agent使用,Skywalking 采用 Java 探针技术,对客户端应用程序没有任何代码侵入,使用起来简单方便,当然其具体实现就是需要针对不同的框架及服务提供探针插件。使用命令:
* java -javaagent:G:\github\incubator-skywalking\skywalking-agent\skywalking-agent.jar --SW_AGENT_NAME=应用名(必须英文) -jar your_application.jar
* 参数说明:
* --SW_AGENT_NAME 定义服务名称,在skywalking ui显示对应服务(8.5.0不添加此参数,默认显示Your_Application。在6.x不需要配置,直接显示spring.application.name的值)
* Agent过滤URL,在SkyWalking的追踪信息页面不再显示(参考:https://www.jianshu.com/p/4bd310850dd0)
* Skywalking的traceId与日志组件(log4j,logback,elk等)的集成,以logback为例,只要在日志配置xml中增加以下配置,则在打印日志的时候,自动把当前上下文中的traceId加入到日志中去,SkyWalking默认traceId占位符是%tid
```
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %tid - %msg%n
```
* 日志上报skywalking配置(skywalking grpc 日志收集 8.4.0版本开始支持)
```
%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} -%msg%n
```
* 日志插件配置,详细配置参考文档:https://skywalking.apache.org/docs/main/v8.5.0/en/setup/service-agent/java-agent/readme/
```
// 配置文件路径:agent\config\agent.config
plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:127.0.0.1}
plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800}
plugin.toolkit.log.grpc.reporter.max_message_size=${SW_GRPC_LOG_MAX_MESSAGE_SIZE:10485760}
plugin.toolkit.log.grpc.reporter.upstream_timeout=${SW_GRPC_LOG_GRPC_UPSTREAM_TIMEOUT:30}
```
* skywalking告警
* skywalking告警支持本地配置和动态配置
* 本地配置:在/config/alarm-settings.yml配置告警规则
* 动态配置(基于nacos):
* 修改/config/application.yml的configuration.selector值,指定nacos作为配置中心
* 在nacos新建dataId=alarm.default.alarm-settings,配置内容跟/config/alarm-settings.yml一样的格式
* 动态规则优先级高于本地规则
* 告警规则key含义
* metrics-name:取值可以在skywalking ui每个指标的编辑(“...”图标)下可以查看,对应中文名称叫指标。实体类型是该指标适用的范围
* include-names:包含在此规则之内的实体名称列表,实例名称规则
* 端点:{端点名称} in {服务名称},例如: GET:/skywalking/pref in luna
* 告警文档:
* https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/dynamic-config.md
* https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/dynamic-config-nacos.md
* https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/backend-alarm.md#entity-name
* skywalking 子线程与主线程输出相同trace id
* 在skywalking-agent.jar目录找到 bootstrap-plugins 文件夹
* bootstrap-plugins/apm-jdk-threading-plugin-8.8.0.jar 复制到 plugins 文件夹下
* config/agent.config的plugin.jdkthreading.threading_class_prefixes配置包含实现多线程类的包路径,
例如:plugin.jdkthreading.threading_class_prefixes=com.demo
目前不支持java 8 CompletableFuture输出trace id
## XXL-JOB
* XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展
## nacos
* 服务注册中心和配置中心使用nacos
* 官网:https://nacos.io/zh-cn/index.html
* 启动
```
startup.cmd -m standalone
```
* 容器部署:https://hub.docker.com/r/nacos/nacos-server
* 下载镜像:docker pull nacos/nacos-server:1.4.2
* 启动容器:docker run --name nacos -e MODE=standalone -p 8848:8848 -d nacos/nacos-server:1.4.2
## canal
* 基于数据库增量日志解析,提供增量数据订阅&消费
* 测试时修改配置文件
* conf\canal.properties
```
// 默认值example,server上部署的instance列表,需要在canal.properties目录下建立同名的目录
canal.destinations = example,example2
```
* conf\example\instance.properties
```
// 数据库地址
canal.instance.master.address=192.168.1.20:3306
// username/password,数据库的用户名和密码
canal.instance.dbUsername = canal
canal.instance.dbPassword = canal
// 默认topic,动态topic规则匹配不到往默认topic投递消息
canal.mq.topic=ds
// 动态topic规则配置
canal.mq.dynamicTopic=.*\\..*
```
* canal配置:https://github.com/alibaba/canal/wiki/Canal-Kafka-RocketMQ-QuickStart
## Sentinel
* Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能
* [网关限流介绍](https://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81#%E7%BD%91%E5%85%B3%E6%B5%81%E6%8E%A7%E6%8E%A7%E5%88%B6%E5%8F%B0)
* 启动命令:java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
* Sentinel 1.7.2之前版本,如果在网关限流必须配置SPI机制加载GatewaySlotChainBuilder才能在网关限流,配置如下:
* 在resources新建目录META-INF.services
* 新建文件,文件名com.alibaba.csp.sentinel.slotchain.SlotChainBuilder
* SlotChainBuilder文件内容:com.alibaba.csp.sentinel.adapter.gateway.common.slot.GatewaySlotChainBuilder
* Sentinel 1.7.2开始不需要SPI配置
## Sentinel-dashboard
* sentinel控制台(已经有1.7.2, 1.8.0 demo)
* 使用sentinel 1.8.0版本,簇点链路自动显示调用过资源名,在1.7.1版本必须在方式加入@SentinelResource才能显示
* 修改sentinel控制台,将配置规则推送到nacos,使规则持久化
* 修改代码 (基于sentinel控制台 1.8.0)
* GatewayApiController API管理持久化
* GatewayFlowRuleController 流控规则持久化
* DegradeController 降级规则持久化
* FlowControllerV2 集群流控规程持久化
* DynamicRuleProvider
* DynamicRulePublisher
* 页面修改 (基于sentinel控制台 1.8.0)
* sidebar.html取消dashboard.flow注释
* 新增类型 (基于sentinel控制台 1.8.0)
* com.alibaba.csp.sentinel.dashboard.config.NacosConfig
* com.alibaba.csp.sentinel.dashboard.rule.GatewayDegradeRuleNacosProvider
* com.alibaba.csp.sentinel.dashboard.rule.GatewayDegradeRuleNacosPublisher
* com.alibaba.csp.sentinel.dashboard.rule.GatewayFlowRuleNacosProvider
* com.alibaba.csp.sentinel.dashboard.rule.GatewayFlowRuleNacosPublisher
* com.alibaba.csp.sentinel.dashboard.rule.GatewayApiRuleNacosProvider
* com.alibaba.csp.sentinel.dashboard.rule.GatewayApiRuleNacosPublisher
* com.alibaba.csp.sentinel.dashboard.rule.ClusterAssignRuleNacosPublisher
* com.alibaba.csp.sentinel.dashboard.rule.ClusterServerNamespaceSetNacosProvider
* com.alibaba.csp.sentinel.dashboard.rule.ClusterServerNamespaceSetNacosPublisher
* com.alibaba.csp.sentinel.dashboard.rule.NacosConfigUtil
* 修改日志
* sentinel控制台 1.7.2 支持网关流控规则持久化
* sentinel控制台 1.8.0 支持集群流控规则持久化
## Sentinel 集群流控服务
* 应用名:service-sentinel-server
* 独立模式,采用独立应用部署
* 嵌入模式,嵌入Web应用,可以启动多个实例分别作为 Token Server 和 Token Client。本Demo采用嵌入模式开发,独立模式部署运行,不嵌入到其他应用服务里
## SEATA
* Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。
* server端配置
* file.conf配置存储模式
* registry.conf配置注册类型
* client端配置
* nacos新建配置,dataId为seataServer.properties,
* 配置内容参考:https://github.com/seata/seata/tree/develop/script/config-center 的config.txt
* 参数说明:https://seata.io/zh-cn/docs/user/configurations.html
## RocketMQ 服务启动
* 设置环境变量
```
// 路径名不能包含空格
ROCKETMQ_HOME="D:\rocketmq"
// 如果系统有多网卡,指定ip。broker启动会读取环境变量去连接name server
NAMESRV_ADDR="localhost:9876"
```
* 启动 Name Server
```
.\bin\mqnamesrv.cmd
```
* 启动 Broker
```
// autoCreateTopicEnable=true 允许应用自动创建topic
// -c 指定加载配置文件路径
.\bin\mqbroker.cmd -n localhost:9876 autoCreateTopicEnable=true -c conf/broker.conf
```
* 官网:http://rocketmq.apache.org/docs/quick-start/
* 容器部署
* 获取docker镜像和部署教程:https://hub.docker.com/r/leixuewen/rocketmq
* broker.conf配置文件里的brokerIP1,namesrvAddr的ip设置为docker虚拟网卡的ip
## RocketMQ 控制台
* 控制台源码和docker镜像:https://github.com/apache/rocketmq-dashboard
* 启动命令修改,替换成docker虚拟网卡ip
```
docker run -d --name rocketmq-dashboard --link rocketmq -e "JAVA_OPTS=-Drocketmq.namesrv.addr=docker虚拟网卡ip:9876" -p 8080:8080 -t apacherocketmq/rocketmq-dashboard:latest
```
## flowable-ui
* Flowable是用Java编写的轻量级业务流程引擎。Flowable流程引擎允许您部署BPMN 2.0流程定义(用于定义流程的行业XML标准),创建
流程定义的流程实例,运行查询,访问活动或历史流程实例以及相关数据等等。本节将逐步介绍各种概念和API,通过您可以在自己的开发
机器上进行的实例进行实现。
* flowable-ui部署:
* 下载镜像:docker pull flowable/flowable-ui:6.7.2
* 将MySQL jar包放在Dockerfile同一目录下(Dockerfi了已经放在spring-cloud-deoo/flowable-ui目录下)
* 修改Dockerfile数据库连接
* 创建镜像,在Dockerfile目录下执行命令: docker build --tag flowable-ui .
* 执行动动命令:docker run --name flowable-ui -p 8080:8080 -t flowable-ui:latest
* flowable-ui使用:
* 地址:http://localhost:8080/flowable-ui。 账号:admin。 密码:test
* 导入工作流文件(在spring-cloud-deoo/flowable-ui目录)
* 新建用户组:老师组(id=teacher),校长组(id=headmaster)
## uid 服务
* 应用名:service-uid
* 全局唯一ID生成服务,使用snowflake算法生成ID
* 实现通过不能命名空间实现ID隔离,不同命名空间可能产生同一个ID
* 压力测试方法:
* com.demo.uid.service.SnowFlakeServiceTest.testParallelNextId