# 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 开启全局事务管理