# dingBike服务端
**Repository Path**: T_hc_admin/ding-bike-server
## Basic Information
- **Project Name**: dingBike服务端
- **Description**: 共享单车java服务端
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2022-05-07
- **Last Updated**: 2022-05-07
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
涉及技术:
一.springCloud-Alibaba 微服务框架----------------------------------------------------------------------------------------------------------------
在主项目pom.xml文件下添加依赖:
org.springframework.cloud
spring-cloud-dependencies
Greenwich.RELEASE
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2.1.0.RELEASE
二.nacos 服务治理--------------------------------------------------------------------------------------------------------------------------------
1.服务端:
(1)下载nacos服务端解压至项目根目录:
https://github.com/alibaba/nacos/releases
(2)启动nacos服务端:
startup.cmd -m standalone
(3)访问nacos,账号密码:nacos
http://localhost:8848/nacos
2.客户端:
(1)在需要实现服务治理的微服务pom.xml文件中添加依赖:
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
2.1.0.RELEASE
(2)在需要实现服务治理的微服务的引导类上添加注解:
@EnableDiscoveryClient//nacos客户端注解
三.fegin 实现多个微服务实例的调用自动负载均衡组件(springboot提供的伪http客户端,使得调用远程服务和调用本地服务一样简单) --代替--》 ribbon微服务负载均衡----------------------------------
(1)在调用者的pom文件中添加fegin坐标
org.springframework.cloud
spring-cloud-starter-openfeign
2.1.0.RELEASE
com.netflix.archaius
archaius-core
(2)在调用者主类上添加注解开启fegin客户端:
@EnableFeignClients
(3)编写一个接口BikeService接口,标记@FeginClient客户端注解:
@FeignClient(
value = "service-bike",//value用于指定nacos下的那个微服务
fallbackFactory = BikeServiceFallBackFactory.class //指定容错类
)
public interface BikeService {
@RequestMapping("/bike/getbike{pid}")
Product findById(@PathVariable Integer pid);
}
(4)在controller类中注入BikeServic接口,并调用其方法
四.sentinel 哨兵容错(预防高并发问题)----------------------------------------------------------------------------------------------------------------
容错的三个核心思想(sentinel的三个重要功能):1.保证自己不被上游服务压垮,2.保证自己不被下游服务拖垮,3.保证外界环境良好
1.sentinel:从多个维度保护服务的稳定性
(1)流量控制
(2)熔断处理
(3)系统负载保护
com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel
2.1.0.RELEASE
在上游 pom.xml 导入 sentinel 依赖:
(1)核心库:不依赖任何框架、库,能够运行所有java运行环境同时对Dubbo/Spring Cloud等框架也有较好支持
/
2.sentinel 组成
\
(2)控制台:基于SpringBoot开发,打包后可以直接运行,不需要额外Tomcat等应用容器
<1>需要安装:https://github.com/alibaba/Sentinel/releases 放到项目同级目录
<2>用cmd命令启动:java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=springcloud-alibaba01 -jar sentinel-1.8.2.jar
<3>在需要的服务中yml文件中配置:
spring:
...
cloud:
nacos:
discovery:
server-addr: localhost:8848
sentinel:
transport:
port: 8899 #跟控制台交流的端口,随意指定一个未使用的端口
dashboard: localhost:8080 #指定控制台服务地址(主机+端口)
<4>访问 http://localhost:8080
3.sentinel 规则持久化:
(1)编写处理类 FilePersistence
(2)在resource资源文件夹下创建 META-INF/services 然后添加文件 com.alibaba.csp.sentinel.init.InitFunc
(3)在 com.alibaba.csp.sentinel.init.InitFunc 文件中添加配置类的全路径 cn.lzh.config.FilePersistence
五.feign整合Sentinel实现容错--------------------------------------------------------------------------------------------------------------------------------
1.在调用者的微服务pom.xml中导入sentinel依赖:
com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel
2.在yml文件中开启feign对sentinel的支持:
feign:
sentinel:
enabled:ture
3.创建容错类:容错类要求必须实现被容错的接口,并为每个方法实现容错方案
@Service
@Slf4j
public class BikeServiceFallBackFactory implements FallbackFactory {
@Override
public BikeService create(Throwable throwable) {
return new BikeService() {
@Override
public Bike findById(Integer pid) {
log.error("错误信息:{}",throwable);//报错信息
Bike bike = new Product();
bike.setP_id(-1);
bike.setP_name("远程调用商品微服务异常");
return bike;
}
};
}
}
(4)为被容错的接口指定容错类(被容错类order的BikeService):
@FeignClient(
value = "service-bike",//value用于指定nacos下的那个微服务
fallbackFactory = BikeServiceFallBackFactory.class //指定容错类
)
六.Gradeway--服务网关--------------------------------------------------------------------------------------------------------------------------------
1.使用Gradeway内部过滤器
(1)新建一个模块 api-gateway
(2)导入依赖:
groupId>com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
org.springframework.cloud
spring-cloud-starter-gateway
(3)创建主类:
添加注解:
@SpringBootApplication
@EnableDiscoverClient
(4)配置yml文件:
server:
port: 7000
spring:
application:
name: API-Gateway
cloud:
gateway:
routes: #路由数组 [路由:当满足什么样的条件时转发到哪个微服务上去]---------可以不配置此条以下,使用默认,访问路由为:http://localhost:7000/service-product/product/1
- id: bike_route #当前路由的唯一标识,要求标识唯一,默认UUID
uri: lb://service-bike # lb:实现负载均衡(内置全局过滤器),service-bike为nacos上的服务名称-----自定义全局过滤器见 7
order: 1 #优先级,1最高
predicates: #断言(条件判断,返回值是boolean)
- Path=/bike-ser/** #当请求路径满足Path指定条件时,此路由会正常转发
- Method=get #允许的请求方法
... 其他
filters: #过滤器(在请求传递过程中,对请求做一些手脚)
- StrpPrefix=1 #在请求转发之前去掉一层路径
...其他
最后形成的访问路由 http://localhost:7000/bike-ser/bike/getall (bike-ser此层路由会被去掉)
2.自定义全局过滤器 AuthGlobalFilter类:
(1)作用:在请求(request)和响应(respond)做一些手脚。
(2)生命周期:
PRE:这种过滤器在请求被路由之前调用,可以用其实现身份验证、集群中选择微服务、记录调式信息等。
POST:这种过滤器在路由到微服务以后执行,可以用来为响应添加标准的http请求头,收集统计信息和指标,将相应从微服务发送给客户端等。
(3)分类:局部过滤器、全局过滤器
(4)需要实现GlobalFilter和Ordered接口,并重写filter, getOrder方法
七.网关限流--------------------------------------------------------------------------------------------------------------------------------
使用sentinel哨兵组件实现对SpringGlobalway网关的限流
1.路由维度
(1)在yml文件中可以添加多个路由:
- id: order_route #当前路由的唯一标识,要求标识唯一,默认UUID
uri: lb://service-product # lb:实现负载均衡(内置全局过滤器),service-product为nacos上的服务名称-----自定义全局过滤器见 7
order: 1 #优先级,1最高
predicates: #断言(条件判断,返回值是boolean)
- Path=/product-ser/** #当请求路径满足Path指定条件时,此路由会正常转发
- Method=get #允许的请求方法
... 其他
filters: #过滤器(在请求传递过程中,对请求做一些手脚)
- StrpPrefix=1 #在请求转发之前去掉一层路径
...其他
(2)在pom.xml文件中添加依赖:
com.alibaba.csp
sentinel-spring-cloud-gateway-adapter
1.8.2
(3)编写自定义分组路由 GateWayConfigration_route 配置类
2.分组维度
(1)在配置类GateWayConfigration_route中编写 initCustomizedApis 自定义API分组
Set definitions = new HashSet<>();
ApiDefinition bike_api = new ApiDefinition("bike_api")
.setPredicateItems(new HashSet(){{
//以 bike-ser/ 开头的请求
add(new ApiPathPredicateItem().setPattern("bike-ser/**") //可以放多个规则
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
ApiDefinition paking_api = new ApiDefinition("paking_api")
.setPredicateItems(new HashSet(){{
//以 product-ser/ 开头的请求
add(new ApiPathPredicateItem().setPattern("bike-ser/**")
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
definitions.add(bike_api);
definitions.add(paking_api);
GatewayApiDefinitionManager.loadApiDefinitions(definitions);
(2)在配置类的 initGatewayRules 初始化参数方法中初始化限流参数:
Set rules= new HashSet<>();
rules.add(new GatewayFlowRule("bike_api").setCount(1).setIntervalSec(1));
rules.add(new GatewayFlowRule("paking_api").setCount(1).setIntervalSec(1));
GatewayRuleManager.loadRules(rules);//加载
九.链路追踪:sleuth+Zipkin
1.SpringCloud Sleuth主要功能是在分布式系统中提供追踪解决方案。
(1)Trace:
由一组Trace id相同的Span串联形成一个树状结构。为实现请求追踪,当请求到达分布式系统入口端点时,服务跟踪框架会为请求创建一个唯一标识TraceID
同时在分布式系统内部流转时,框架始终保持传递唯一值,直到整个请求的返回。因此可以将所有请求串联形成完整的请求链路。
(2)Span:
代表一组基本工作单元,统计各个处理单元的延迟,当请求到达各个服务组件时,也通过一个唯一标识(SpanId)来标记其开始,具体过程和结束。通过SpanId
的开始和结束时间戳,就可以统计该Span的调用时间,还可以获取事件名,请求信息等元数据。
(3)Annotation:
用它记录一段时间内的时间,内部使用的重要注解
cs(Client Send)客户端发出请求,开始一个请求生命
sr(Send Received)服务端接收到请求开始处理,sr-cs=网络延迟(调用服务时间)
ss(Server Send)服务端处理完毕准备发送到客户端,ss-sr=服务器上的请求处理时间
cr(Client Received)客户端接收到服务端的响应,请求结束。cr-sr=请求的总时间
(4)sleuth的使用:
在主pom.xml文件中添加sleuth依赖:
org.springframework.cloud
spring-cloud-starter-sleuth
2.Zipkin
Zipkin分为服务端与客户端(微服务应用),客户端配置服务端的URL地址一旦发生服务端的调用时,会被配置微服务的Slueth的监听器监听,并生成Trace和Span信息发送给服务端。
zipkin主要负责微服务架构中的网络延迟问题,包括数据的收集(collector组件)、存储(Storage存储组件)、查找(RESTful API)和展现(Web UI)。
1.服务端:
(1)下载Zipkin的jar包
https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec
(2)命令行启动Zipkin:
java -jar zipkin-server-2.12.9-exec.jar
(3)通过浏览器访问:
http://localhost:9411
2.客户端:
(1)在父工程上添加依赖:
org.springframework.cloud
spring-cloud-starter-zipkin
(2)在每个微服务上添加配置:
spring:
zipkin:
base-url: http://localhost:9411/ #zipkin的请求地址
discoveryClientEnabled: false #让nacos把它当成一个URL,而不要当做服务名
sleuth:
sampler:
probability: 1.0 #采样百分比
(3)访问微服务:
http://localhost:7000/bike-ser/bike/getall
/ 存入mysql数据库
(4)zipkin数据持久化
\ 使用elasticsearch实现数据持久:
<1>下载elasticsearch: https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-8-4
<2>下载完成以后解压并放到公国目录,进入bin目录双击elasticsearch.bat打开服务
<2>重启 zipkin server 服务端: java -jar zipkin-server-2.12.9-exec.jar --STORAGE_TYPE=elasticsearch --ES-HOST=localhost:9200
(5)访问zipkin的UI界面,观察效果
十.kafka企业级消息队列:
1.kafka服务端---临时存储和传递消息:
(1).启动zookeepe服务端(linux):
启动:
bin/zkServer.sh start
重启:
./zkServer.sh restart
查看状态:
./zkServer.sh status
(2).启动zookeeper客户端(linux):
bin/zkCli.sh -server 127.0.0.1:2181
(3).启动kafka
<1>需要先启动Zookeeper:
# 注意:Apache Kafka2.8版本之后可以不需要使用ZooKeeper
bin/zookeeper-server-start.sh config/zookeeper.properties
<2>启动kafka服务:
bin/kafka-server-start.sh config/server.properties &
2.kefka客户端的使用:
(1)在主项目中pom.xml添加kafka依赖:
org.springframework.kafka
spring-kafka
org.apache.kafka
kafka-clients
${kafka.version}
十一.Nacos Config统一配置管理
讲配置文件统一放在nacos上,然后各个微服务nacos上拉取配置信息。
1.在每个微服务上添加配置依赖
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
2.在微服务中添加nacos config配置
配置文件的优先级:bootstrap.properties --> bootstrap.yml --> application.properties --> application.yml
在各个微服务中新建一个 bootstrap.yml 配置文件:
spring:
application:
name: service-gateway #对应 nacos 上的 Data ID = service-gateway-dev.yaml
cloud:
nacos:
config:
server-addr: localhost:8848 #nacos中心地址
file-extension: yaml #配置文件格式
profiles:
active: dev #环境标识(dev生产环境)
3.实现配置文件的动态更新:
在访问控制层添加注解:
(1)类注解:@RefreshScope
4.不同微服务之间的配置共享(发布在nacos上的公共配置文件 all-service.yaml):
在 bootstrap 配置文件中引入:
spring:
cloud:
nacos:
config:
shared-dataids: all-service.yaml #配置引入的配置
refreshable-dataids: all-service.yaml #配置要实现动态配置刷新的配置
十二.Seata事务
让分布式事务的使用和本地事务一样简单使用、高效。它对业务无侵入性
TC: Transaction Coordinator事务协调器,管理全局的分支事务状态,用于全局性事务的提交和回滚。
/
1.Seata三个重要组件 -- TM: Transaction Manager 事务管理器,用于开启、提交或者事务回滚全局事务
\
RM: Resource Manager 资源管理器,用于分支事务上的资源管理,向TC注册分支事务,上报分支事务的状态,
接收TC的命令来提交或回滚分支事务。
2.下载Seata : https://github.com/seata/seata/releases/v0.9.0
3.修改配置文件:
(1)将下载得到的压缩包进行解压,进入config目录,调整registry.conf的配置:
registry {
type = "nacos"
nacos {
serverAddr = "localhost"
nameSpace = "public"
cluster = "default"
}
}
config {
type = "nacos"
nacos {
serverAddr = "localhost"
nameSpace = "public"
cluster = "default"
}
}
(2)修改nacos-config.txt文件:
service.vgroup_mapping.service-product=default
service.vgroup_mapping.service-order=default
4.初始化seata在nacos的配置,需要保证nacos已经运行,成功以后可以看见在nacos的配置列表中初始化了大量Group配置:
cd conf
nacos-config.sh 127.0.0.1
5.启动seata服务,可在nacos的服务列表看到一个serverAddr的服务:
cd bin
seata-server.bat -p 9000 -m file
6.使用seata实现事务控制(提交和回滚)
(1)初始化数据库表(日志记录):
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) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE = INNODB
AUTO_INCREMENT = 1
DEFAUT CHARSET = utf8;
7.在每个需要进行事务管理的微服务添加如下配置:
实现拉取nacos上的配置信息:
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
2.1.0.RELEASE
Seata的TM(事务管理器)、RM(资源管理器)集成依赖:
com.alibaba.cloud
spring-cloud-starter-alibaba-seata
2.1.0.RELEASE
8.Seata通过代理数据源实现事务分支,需要配置 io.seata.rm.datasource.DataSourceProxy 的 Bean,且是默认的@Primary数据源,否则事务会不会回滚,无法实现分布式事务
在需要事务管理的微服务中的config包下新创建类DataSourceProxyConfig:
@Configuration
public class DataSourceProxyConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DruidDataSource druidDataSource(){
return new DruidDataSource();
}
@Primary
@Bean
public DataSourceProxy dataSourceProxy(DruidDataSource druidDataSource){
return new DataSourceProxy(druidDataSource);
}
}
9.在需要事务管理的微服务资源文件夹下添加seata的registry.conf文件:
registry {
type = "nacos"
nacos {
serverAddr = "localhost"
nameSpace = "public"
cluster = "default"
}
}
config {
type = "nacos"
nacos {
serverAddr = "localhost"
nameSpace = "public"
cluster = "default"
}
}
10.在需要事务管理的微服务下的资源文件 bootstrap.yml 文件添加配置:
spring:
application:
name: service-product #对应 nacos 上的 Data ID = service-product-dev.yaml
cloud:
nacos:
config:
server-addr: localhost:8848 #nacos中心地址
file-extension: yaml #配置文件格式
namespace: public ------------------------------新添加
group: SEATA_GROUP ------------------------------新添加
alibaba: ------------------------------新添加
seata: ------------------------------新添加
tx-service-group: order-service #与seata的 nacos-config.txt 的service.vgroup_mapping.product-service=default对应 ------------------------------新添加
profiles:
active: dev #环境标识(dev生产环境)
11.在需要事务管理的类方法上添加注解 @GlobalTransactional 开启全局事务管理