做好政府網(wǎng)站建設(shè)工作的通知安卓神級(jí)系統(tǒng)優(yōu)化工具
項(xiàng)目地址:源代碼
僅作為學(xué)習(xí)用例使用,是我開(kāi)發(fā)過(guò)程中的總結(jié)、實(shí)際的一部分使用方式
開(kāi)發(fā)環(huán)境:
jdk11
springboot2.7.6
springcloud2021.0.5
alibabacloud 2021.0.4.0
redis6.0
mysql8.0
一、項(xiàng)目搭建
wdz-api:存放遠(yuǎn)程服務(wù)調(diào)用相關(guān)接口
wdz-auth:認(rèn)證業(yè)務(wù)
wdz-gateway:網(wǎng)關(guān)
wdz-modules:業(yè)務(wù)模塊微服務(wù)
wdz-common:存放公用中間件、數(shù)據(jù)庫(kù)等服務(wù)
pom
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><modules><module>wdz-common</module><module>wdz-gateway</module><module>wdz-api</module><module>wdz-auth</module><module>wdz-modules</module></modules><groupId>com.wdz</groupId><artifactId>wdz-ruzhou</artifactId><version>1.0.0</version><name>wdz-ruzhou</name><description>微服務(wù)架構(gòu)</description><properties><java.version>11</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.7.6</spring-boot.version><spring-cloud.version>2021.0.5</spring-cloud.version><spring-cloud.alibaba>2021.0.4.0</spring-cloud.alibaba><fastjson2.version>2.0.14</fastjson2.version><lombok.version>1.18.24</lombok.version></properties><dependencyManagement><dependencies><!--springcloud 微服務(wù)依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><!--springboot 依賴--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><!--alibaba 微服務(wù)依賴--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud.alibaba}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>${fastjson2.version}</version></dependency></dependencies></dependencyManagement><!--配置打包環(huán)境數(shù)據(jù)--><profiles><profile><id>dev</id><properties><profiles.active>dev</profiles.active><nacos.username>nacos</nacos.username><nacos.password>nacos</nacos.password><nacos.server>127.0.0.1:8848</nacos.server><nacos.discovery.namespace>5efed786-91f6-44c4-8e14-049df72b2a48</nacos.discovery.namespace><nacos.config.namespace>5efed786-91f6-44c4-8e14-049df72b2a48</nacos.config.namespace></properties><activation><activeByDefault>true</activeByDefault></activation></profile><profile><id>test</id><properties><profiles.active>test</profiles.active><nacos.username>nacos</nacos.username><nacos.password>nacos</nacos.password><nacos.server>127.0.0.1:8848</nacos.server><nacos.discovery.namespace>f02ccd30-e3d5-4235-9282-d0a613bd322b</nacos.discovery.namespace><nacos.config.namespace>f02ccd30-e3d5-4235-9282-d0a613bd322b</nacos.config.namespace></properties></profile><profile><id>prod</id><properties><profiles.active>prod</profiles.active><nacos.username>nacos</nacos.username><nacos.password>nacos</nacos.password><nacos.server>127.0.0.1:8848</nacos.server><nacos.discovery.namespace>747829ca-6d8a-4417-a46a-bd31a6f5e442</nacos.discovery.namespace><nacos.config.namespace>747829ca-6d8a-4417-a46a-bd31a6f5e442</nacos.config.namespace></properties></profile></profiles><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>3.0.0</version></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>${java.version}</source><target>${java.version}</target><encoding>${project.build.sourceEncoding}</encoding></configuration></plugin></plugins><!--用于yml配置中變量替換如: @nacos.name@--><resources><resource><directory>src/main/resources</directory><!-- 引入所有 匹配文件進(jìn)行過(guò)濾 --><includes><include>application*</include><include>bootstrap*</include><include>logback*</include></includes><!-- 啟用過(guò)濾 即該資源中的變量將會(huì)被過(guò)濾器中的值替換 --><filtering>true</filtering></resource></resources></build>
</project>
nacos(2.2.0.1)
我為什么選擇nacos作為注冊(cè)中心?
1、獨(dú)立的可視化管理后臺(tái)
2、持久化,配置數(shù)據(jù)直接存儲(chǔ)在數(shù)據(jù)庫(kù)中
3、動(dòng)態(tài)配置,修改配置可實(shí)時(shí)生效,不用重啟
4、活躍度高,資料文件豐富
5、功能全面
6、是經(jīng)過(guò)阿里巴巴考驗(yàn)的
戳==>官網(wǎng)
安裝nacos
點(diǎn)擊選擇版本下載
windows建議下載zip
linux 建議下載tar.gz
下載完成解壓即可
配置數(shù)據(jù)庫(kù)
打開(kāi)conf下的application.properties文件:
修改數(shù)據(jù)庫(kù)配置,將注釋打開(kāi),并配置數(shù)據(jù)源
創(chuàng)建數(shù)據(jù)庫(kù)目前只支持mysql,版本要求:5.6.5+
需要IPV6支持使用:derby-schema.sql 否則使用:mysql-schema.sql 配置完成后
單機(jī)啟動(dòng)nacos:
Linux/Unix/Mac使用命令:sh startup.sh -m standalone
windows使用命令:./startup.cmd -m standalone
standalone:表示單機(jī)模式運(yùn)行,非集群模式
官方文檔
啟動(dòng)過(guò)程中如果出現(xiàn)jwt認(rèn)證問(wèn)題啟動(dòng)失敗,請(qǐng)參考:戳詳情
錯(cuò)誤示例
修改文件:
nacos.core.auth.plugin.nacos.token.secret.key
使用base64 處理數(shù)據(jù)長(zhǎng)度大于等于32即可
訪問(wèn):http://localhost:8848/nacos,默認(rèn)用戶名密碼:nacos
集群?jiǎn)?dòng) 官方文檔
如果是在一臺(tái)電腦上/服務(wù)器上模擬集群:
將nacos解壓之后的文件nacos復(fù)制多份,
并修改對(duì)應(yīng)conf文件夾下的application.properties文件端口配置
再將conf下的cluster.conf.example 復(fù)制一份并修改后綴為conf
將其他nacos地址配置在cluster.conf中
依次啟動(dòng)服務(wù):
windows命令:./startup.cmd
linux命令: sh ./startup.sh
訪問(wèn)對(duì)應(yīng)nacos
nacos 服務(wù)配置config與發(fā)現(xiàn) discovery
創(chuàng)建測(cè)試注冊(cè)服務(wù)網(wǎng)關(guān)服務(wù),nacos作為注冊(cè)中心有多種方式,本文用javaSDK的方式
pom文件
<?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"><parent><artifactId>wdz-ruzhou</artifactId><groupId>com.wdz</groupId><version>1.0.0</version></parent><modelVersion>4.0.0</modelVersion><groupId>com.wdz</groupId><artifactId>wdz-gateway</artifactId><packaging>jar</packaging><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
yml配置:
server:port: 8080servlet:context-path: /spring:application:name: wdz-gatewayprofiles:active: @profiles.active@
---
# 使用導(dǎo)入的方式讀取所有需要的nacos中的配置文件
spring:config:import:- optional:nacos:application-common.yml- optional:nacos:${spring.application.name}.ymlcloud:nacos:username: @nacos.username@password: @nacos.password@server-addr: @nacos.server@# 服務(wù)發(fā)現(xiàn)discovery:namespace: @nacos.discovery.namespace@# 配置config:namespace: @nacos.config.namespace@
集群nacos負(fù)載配置:
通過(guò)nginx配置服務(wù)訪問(wèn)的nacos
upstream nacos-cluster{server 127.0.0.1:8247;server 127.0.0.1:8549;server 127.0.0.1:8848;
}
server{listen 801;server_name localhost;location /nacos{proxy_pass http://nacos-cluster;}
}
結(jié)果
負(fù)載均衡Ribbon
內(nèi)置負(fù)載均衡規(guī)則類 | 規(guī)則描述 |
---|---|
RoundRobinRule | 簡(jiǎn)單輪詢服務(wù)列表選擇服務(wù)器,它是Ribbon默認(rèn)的負(fù)載均衡規(guī)則 |
AvailabilityFilteringRule | 忽略規(guī)則:1、鏈接3次失敗,會(huì)標(biāo)記為短路狀態(tài),將持續(xù)30秒,如果還是失敗則持續(xù)短路,時(shí)間增長(zhǎng),2、并發(fā)數(shù)過(guò)高的服務(wù)鏈接,并發(fā)數(shù)達(dá)到上限則會(huì)被忽略 |
WeightedResponseTimeRule | 權(quán)重策略,每個(gè)服務(wù)器配置一個(gè)權(quán)重值,權(quán)重值越小,選擇這個(gè)服務(wù)器的比重就會(huì)越小 |
ZoneAvooidanceRule | 以區(qū)域可用的服務(wù)器為基礎(chǔ)進(jìn)行服務(wù)器的選擇,使用Zone對(duì)服務(wù)器進(jìn)行分類,Zone相當(dāng)于一個(gè)機(jī)房,一個(gè)區(qū)域,然后再對(duì)Zone內(nèi)的多個(gè)服務(wù)做輪詢 |
BestAvailableRule | 忽略哪些短路服務(wù)器,并選擇并發(fā)數(shù)較低的服務(wù)器 |
RandomRule | 隨機(jī)選擇一個(gè)可用服務(wù)器 |
RetryRule | 重試機(jī)制的選擇邏輯 |
自定義策略方式:
代碼方式:作用的是所有服務(wù)
@Bean
public IRule diyRule(){return new RandomRule();
}
yml方式:作用的是所配置的服務(wù)
servicename: # 服務(wù)名稱如:userserviceribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
ribbon默認(rèn)是懶加載,第一次訪問(wèn)的時(shí)候響應(yīng)時(shí)間會(huì)比較長(zhǎng),初次加載之后響應(yīng)就會(huì)變短。
開(kāi)啟ribbon饑餓加載有效提高第一次訪問(wèn)響應(yīng)時(shí)間
ribbon:eager-load:enabled: true # 開(kāi)啟饑餓加載clients: # 指定加載的服務(wù)名稱- userservice- orderservice- systemservice- XXXservice
nacos服務(wù)分級(jí)存儲(chǔ)模型
一級(jí)是服務(wù):如:userservice、orderservice
二級(jí)是集群:配置了同一個(gè)discovery.cluster-name:
三級(jí)是實(shí)例:如杭州機(jī)房的某臺(tái)部署了要訪問(wèn)的服務(wù)器
設(shè)置實(shí)例的集群屬性:名稱一樣的在同一個(gè)集群內(nèi)
spring.cloud.nacos.discovery.cluster-name:NacosRule負(fù)載均衡策略:
1、優(yōu)先選擇同集群的服務(wù)
2、本地集群找不到提供者,才去其他集群找,并且會(huì)報(bào)警告
3、確定了可用實(shí)例列表后,再采用隨機(jī)負(fù)載均衡挑選實(shí)例
NacosRule配置:
servicename: # 服務(wù)名稱如:userserviceribbon:NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
環(huán)境隔離:namespace
spring:cloud:nacos:discovery:namespace: @nacos.discovery.namespace@
# 不同名稱空間之間的服務(wù)不能互通,如user使用的prod order使用的dev,這兩個(gè)服務(wù)不能互通
nacos特點(diǎn)
1、支持服務(wù)端主動(dòng)監(jiān)測(cè)提供者狀態(tài),臨時(shí)實(shí)例采用心跳模式,非臨時(shí)實(shí)例采用主動(dòng)監(jiān)測(cè)模式
2、林實(shí)施例心跳不正常會(huì)被剔除nacos的服務(wù)列表,非臨時(shí)實(shí)例不會(huì)被剔除
3、服務(wù)列表變更消息推送模式,服務(wù)列表更新及時(shí)
4、nacos集群默認(rèn)采用AP方式,集群中存在非臨時(shí)實(shí)例時(shí),采用CP模式
CAP:C(一致性),A(可用性),P(分區(qū)容錯(cuò))原文
Feign 源碼
feign是聲明式的http客戶端
使用方式
pom引入依賴
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
java代碼
@FeignClient("applicationName")
public interface ApplicationName{@GetMapping("/get")Object queryById(Long id);
}
自定義feign配置
類型 作用 說(shuō)明 feign.Logger.Level 修改日志級(jí)別 包含四種不同的級(jí)別:none、basic、headers、full feign.codec.Decoder 響應(yīng)結(jié)果解析器 http遠(yuǎn)程調(diào)用的結(jié)果做解析,例如解析json字符串為java對(duì)象 feign.codec.Encoder 請(qǐng)求參數(shù)編碼 將請(qǐng)求參數(shù)編碼,便于通過(guò)http請(qǐng)求發(fā)送 feign.Contract 支持注解格式 默認(rèn)是SpringMvc的注解 feign.Retryer 失敗重試機(jī)制 請(qǐng)求失敗的重試機(jī)制,默認(rèn)沒(méi)有,會(huì)使用Ribbon的重試 none: 不記錄日志
basic:只記錄請(qǐng)求方法和URL以及響應(yīng)狀態(tài)代碼和執(zhí)行時(shí)間
headers:記錄基本信息以及請(qǐng)求和響應(yīng)標(biāo)頭
full:記錄請(qǐng)求和響應(yīng)的頭部、主體和元數(shù)據(jù)
yml日志配置
feign:client:config:default: # DETAULT 是全局配置,如果換成application.name 則是指定服務(wù)有效loggerLevel: FULL
feign:client:config:userservice: # 針對(duì)userservice有效loggerLevel: FULL
代碼方式:
public class FeignClientConfig{@Beanpublic Logger.Level feignLogLevel(){return Logger.Level.BASIC;}
}
然后將該配置添加到:
全局配置方式啟動(dòng)類上
EnableFeignClients(defaultConfiguration=FeignClentConfig.class)
局部配置方式
@FeignClient(value="applicationname",configuration=FeignClientConfig)
feign性能優(yōu)化
URLConnection:默認(rèn)實(shí)現(xiàn),不支持連接池
Apache HttpClient:支持鏈接池
OKHttp:支持連接池
因?yàn)閔ttp鏈接時(shí)要三次握手,斷開(kāi)時(shí)要4次揮手,導(dǎo)致的性能浪費(fèi)
優(yōu)化的性能主要包括:
1、使用連接池代替默認(rèn)的URLConnection
2、日志級(jí)別,最好用basic或none,日志也會(huì)浪費(fèi)性能
連接池配置:
引入依賴
<!--優(yōu)化feignURLConnection-->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId>
</dependency>
配置yml
feign:httpclient:enabled: true # 開(kāi)啟feign對(duì)httpClient的支持max-connections: 200 # 最大鏈接數(shù) 可根據(jù)測(cè)試結(jié)果最優(yōu)配置max-connections-per-route: 50 # 每個(gè)路徑最大鏈接數(shù) 可根據(jù)測(cè)試結(jié)果最優(yōu)配置
實(shí)踐:
system項(xiàng)目引用
EnableFeignClients.clients 指定feignClient接口,及默認(rèn)配置
如果發(fā)現(xiàn)RemoteUserService 加載不到提示,spring-cloud-starter-loadbalancer依賴缺失
在api中添加依賴:負(fù)載均衡依賴
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
測(cè)試接口
目標(biāo)服務(wù)接口
測(cè)試結(jié)果:
SpringAMQP
springboot封裝的消息隊(duì)列,使用的是rabbitmq
生產(chǎn)端
引入依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>
配置
spring:rabbitmq:host: 127.0.0.1 # 主機(jī)port: 5672 # 端口virtual-host: / # 虛擬主機(jī)username: rabbitmq # 用戶名password: 123456 # 密碼
消費(fèi)端
引入依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>
配置
spring:rabbitmq:host: 127.0.0.1 # 主機(jī)port: 5672 # 端口virtual-host: / # 虛擬主機(jī)username: rabbitmq # 用戶名password: 123456 # 密碼
監(jiān)聽(tīng)java代碼:
@Component
public class RabbitMqListener {@RabbitListener(queues = "mq-user")public void listenerQueueMsg(String msg){System.out.println(msg);}
}
如果提示異常:隊(duì)列不存在,且啟動(dòng)失敗
添加配置:
@Configuration
public class RabbitMqConfig {@Beanpublic Queue initQueue(){return new Queue("mq-user");}
}
由于rabbitmq的消費(fèi)預(yù)取機(jī)制,會(huì)導(dǎo)致處理能力弱的消費(fèi)端處理速度變慢,所以限制預(yù)取信息條數(shù)
spring:rabbitmq:listener:simple:prefetch: 1 # 每次只能獲取一條消息,處理完成之后才能獲取下一個(gè)
監(jiān)聽(tīng)端信息:
@Slf4j
@Component
public class RabbitMqListener {@RabbitListener(queues = "mq-user")public void listenerQueueMsg(String msg) {log.info("[listenerQueueMsg]=========:{}",msg);}@RabbitListener(queues = "mq-user")public void listenerQueueMsg2(String msg) {log.info("[listenerQueueMsg2]=========:{}",msg);}
}
消息發(fā)布/訂閱
發(fā)布訂閱模式允許將同一消息發(fā)送給多個(gè)消費(fèi)者,實(shí)現(xiàn)方式是加入exchange(交換機(jī)):
fanout:廣播
direct:路由
topic:話題
交換機(jī)只處理轉(zhuǎn)發(fā),會(huì)造成消息丟失
FanoutExchange 方式
發(fā)送消息用戶服務(wù):
@GetMapping("/send")public LoginUser send(String username) {String queueName = "demo.fanout";String message = username;rabbitTemplate.convertAndSend(queueName,"", message);return new LoginUser(1L, username, "123456");}@GetMapping("/to")public LoginUser to(String username) {String queueName = "demo.fanout";String message = username;rabbitTemplate.convertAndSend(queueName,"", message);return new LoginUser(1L, username, "123456");}
接收消息 system服務(wù):
監(jiān)聽(tīng)代碼@RabbitListener(queues = "demo.fanout2")public void listenerFanoutMsg2(String msg) {log.info("[demo.fanout2]=========:{}", msg);}
@Configuration
public class FanoutExchangeConfig {/*** 一個(gè)消息多個(gè)消費(fèi)者監(jiān)* fanout 廣播模式* 定義交換機(jī)*/@Beanpublic FanoutExchange fanoutExchange() {return new FanoutExchange("demo.fanout");}@Beanpublic Queue fanoutQueue() {return new Queue("demo.fanout");}/*** 綁定交換機(jī)與隊(duì)列關(guān)系** @param fanoutExchange* @param fanoutQueue* @return*/@Beanpublic Binding fanoutBinding(FanoutExchange fanoutExchange,Queue fanoutQueue) {return BindingBuilder.bind(fanoutQueue).to(fanoutExchange);}
}
接收消息 order服務(wù):
監(jiān)聽(tīng)
@Slf4j
@Component
public class RabbitMqListener {@RabbitListener(queues = "demo.fanout")public void listenerFanoutMsg(String msg) {log.info("[demo.fanout]=========:{}", msg);}
}
fanout 配置
@Configuration
public class FanoutExchangeConfig {/*** 一個(gè)消息多個(gè)消費(fèi)者監(jiān)* fanout 廣播模式* 定義交換機(jī)*/@Beanpublic FanoutExchange fanoutExchange() {return new FanoutExchange("demo.fanout");}@Beanpublic Queue fanoutQueue() {return new Queue("demo.fanout2");}/*** 綁定交換機(jī)與隊(duì)列關(guān)系** @param fanoutExchange* @param fanoutQueue* @return*/@Beanpublic Binding fanoutBinding(FanoutExchange fanoutExchange,Queue fanoutQueue) {return BindingBuilder.bind(fanoutQueue).to(fanoutExchange);}
}
均可接收到消息
DirectExchange 方式
direct exchange 會(huì)將接收到的消息根據(jù)規(guī)則路由到指定的queue
每個(gè)queue都與exchange設(shè)置一個(gè)bindingkey
發(fā)布者發(fā)送消息時(shí)指定消息的RoutingKey
exchange將消息路由到BingingKey與消息RoutingKey一致的隊(duì)列
order/system中的監(jiān)聽(tīng)
// 注解方式處理監(jiān)聽(tīng)信息
// bindings 代碼實(shí)現(xiàn)的Binding
// @QueueBinding 綁定信息
// value = @Queue(name = "direct.queue")綁定消息隊(duì)列
// exchange = @Exchange(name = "demo.direct",type = ExchangeTypes.DIRECT)
// 綁定交換機(jī),名稱是demo.direct 類型是direct
// key 是direct模式的主要配置,可同時(shí)監(jiān)聽(tīng)多個(gè)key
@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "direct.queue"),exchange = @Exchange(name = "demo.direct",type = ExchangeTypes.DIRECT),key = {"system","direct"}))public void listenerMessage(String msg) {log.info("[system.direct]=========:{}", msg);}
消息發(fā)送者:
/***@param exchange 交換機(jī)名稱*@param message 消息內(nèi)容*@param routingKey direct 路由key*@return*/@GetMapping("/direct")public void direct(String exchange,String message,String routingKey) {rabbitTemplate.convertAndSend(exchange,routingKey, message);}
發(fā)送信息:
http://localhost/user/direct?exchange=demo.direct&message=發(fā)送的消息內(nèi)容&routingKey=system
Topic 方式
topic方式與direct方式類似,只是key由精準(zhǔn)匹配轉(zhuǎn)換為模糊匹配
// 監(jiān)聽(tīng)@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "topic.queue"),exchange = @Exchange(name = "topic-wdz",type = ExchangeTypes.TOPIC),key = "#.order"))public void listenerTopicMessage(String msg) {log.info("[listenerTopicMessage]=========:{}", msg);}
發(fā)送
@GetMapping("/direct")
public void direct(String exchange,String message,String routingKey) {rabbitTemplate.convertAndSend(exchange,routingKey, message);
}
優(yōu)化
由于springamqp默認(rèn)使用的是jdk默認(rèn)的序列化(ObjectOutputStream)方式,性能問(wèn)題有待提升。
更換為JSON方式序列化。
生產(chǎn)者/消費(fèi)者引入依賴
<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformats-binary</artifactId><version>2.13.4</version></dependency>
初始化bean即可
@Bean
publicMessageConverter messageConverter(){return new Jackson2JsonMessageConverter();
}
Sentinel
分布式事務(wù)seata
事務(wù)(transaction):遵守ACID原則
原子性(Atomicity):事務(wù)中的所有操作,要么全部成功,要么全部失敗
一致性(consistency):要保證數(shù)據(jù)庫(kù)內(nèi)部完整性的約束、聲明性約束
隔離性(isolation):對(duì)同一自愿操作的事務(wù)不能同時(shí)發(fā)生
持久性(durability):對(duì)數(shù)據(jù)庫(kù)的一切修改將永久保存,不管是否出現(xiàn)故障
演示案例:
下單流程:
訂單服務(wù)創(chuàng)建訂單–>賬戶服務(wù)扣減余額–>商品服務(wù)扣減庫(kù)存
1、訪問(wèn)訂單服務(wù)創(chuàng)建訂單
2、通過(guò)feign調(diào)用user扣減余額
3、通過(guò)feign調(diào)用goods扣減庫(kù)存
feign接口
@FeignClient(value = "wdz-goods")
public interface RemoteGoodsService {@GetMapping("/goods/subtractStock")void subtractStock(@PathVariable("username") String username);}
@FeignClient(value = "wdz-user")
public interface RemoteUserService {@GetMapping("/user/subtractBalance")void subtractBalance();
}
控制器代碼
訂單服務(wù)控制器
@RestController
@RequestMapping("order")
public class OrderController {@Autowiredprivate RemoteGoodsService remoteGoodsService;@Autowiredprivate RemoteUserService remoteUserService;@GetMapping("create")public void create(){System.out.println("訂單服務(wù):創(chuàng)建了訂單");remoteGoodsService.subtractStock();remoteUserService.subtractBalance();}
}
用戶服務(wù)控制器代碼
@RestController
@RequestMapping("user")
public class UserController {@GetMapping("subtractBalance")public void subtractBalance(){System.out.println("用戶服務(wù):減余額");}
}
商品控制器代碼
@RestController
@RequestMapping("goods")
public class GoodsController {@GetMapping("subtractStock")public void subtractStock(){System.out.println("商品服務(wù):減少了庫(kù)存");}
}
依次啟動(dòng)nacos-->gateway-->user-->goods-->order
訪問(wèn):http://localhost:8080/order/order/create
訂單服務(wù):創(chuàng)建了訂單
用戶服務(wù):減余額
商品服務(wù):減少了庫(kù)存