Sentinel原理與SpringBoot整合實戰(zhàn)案例講解
前言
隨著微服務(wù)架構(gòu)的廣泛應(yīng)用,服務(wù)和服務(wù)之間的穩(wěn)定性變得越來越重要。在高并發(fā)場景下,如何保障服務(wù)的穩(wěn)定性和可用性成為了一個關(guān)鍵問題。阿里巴巴開源的Sentinel作為一個面向分布式服務(wù)架構(gòu)的流量控制組件,提供了從流量控制、熔斷降級、系統(tǒng)負載保護等多個維度來保障服務(wù)穩(wěn)定性的解決方案。
本文將詳細介紹Sentinel的核心原理和基本功能點,并提供一個完整的SpringBoot整合Sentinel的案例,幫助讀者快速掌握Sentinel的使用方法。
一、Sentinel簡介
1.1 什么是Sentinel
Sentinel是阿里巴巴開源的,面向分布式服務(wù)架構(gòu)的流量控制組件,主要以流量為切入點,從流量控制、熔斷降級、系統(tǒng)負載保護等多個維度來保障服務(wù)的穩(wěn)定性。
Sentinel的主要特性包括:
- 豐富的應(yīng)用場景:Sentinel承接了阿里巴巴近10年的雙十一大促流量的核心場景,例如秒殺(即突發(fā)流量控制在系統(tǒng)容量可以承受的范圍)、消息削峰填谷、集群流量控制、實時熔斷下游不可用應(yīng)用等。
- 完備的實時監(jiān)控:Sentinel同時提供實時的監(jiān)控功能。用戶可以在控制臺中看到接入應(yīng)用的單臺機器秒級數(shù)據(jù),甚至500臺以下規(guī)模的集群的匯總運行情況。
- 廣泛的開源生態(tài):Sentinel提供開箱即用的與其它開源框架/庫的整合模塊,例如與Spring Cloud、Apache Dubbo、gRPC、Quarkus的整合。用戶只需要引入相應(yīng)的依賴并進行簡單的配置即可快速地接入Sentinel。同時Sentinel提供Java/Go/C++等多語言的原生實現(xiàn)。
- 完善的SPI擴展機制:Sentinel提供簡單易用、完善的SPI擴展接口。用戶可以通過實現(xiàn)擴展接口來快速地定制邏輯。例如定制規(guī)則管理、適配動態(tài)數(shù)據(jù)源等。
1.2 Sentinel與其他熔斷降級工具的對比
相比于其他熔斷降級工具(如Hystrix),Sentinel具有以下優(yōu)勢:
- 豐富的流量控制:Sentinel提供了更豐富的流量控制策略,包括基于調(diào)用關(guān)系的流量控制、熱點參數(shù)限流等。
- 實時監(jiān)控:Sentinel提供了實時的監(jiān)控功能,可以實時查看接入應(yīng)用的運行情況。
- 輕量級設(shè)計:Sentinel采用輕量級設(shè)計,不依賴任何框架/庫,能夠運行于所有Java運行時環(huán)境。
- 多語言支持:Sentinel提供了Java/Go/C++等多語言的原生實現(xiàn)。
- 完善的SPI擴展機制:Sentinel提供了完善的SPI擴展接口,用戶可以通過實現(xiàn)擴展接口來快速地定制邏輯。
二、Sentinel核心原理
2.1 基本工作原理
Sentinel的核心工作原理可以概括為:
- 資源定義:資源是Sentinel的核心概念,它可以是Java應(yīng)用程序中的任何內(nèi)容,例如,由應(yīng)用程序提供的服務(wù),或由應(yīng)用程序調(diào)用的其它應(yīng)用提供的服務(wù),甚至可以是一段代碼。只要通過Sentinel API定義的代碼,就是資源。
- 規(guī)則配置:Sentinel通過規(guī)則來指定資源的訪問控制策略。規(guī)則包括流量控制規(guī)則、熔斷降級規(guī)則、系統(tǒng)保護規(guī)則、來源訪問控制規(guī)則和熱點參數(shù)規(guī)則等。
- 統(tǒng)計與判斷:Sentinel會實時統(tǒng)計資源的調(diào)用數(shù)據(jù),并根據(jù)預(yù)設(shè)的規(guī)則進行判斷,若超出閾值,則采取相應(yīng)的流量控制措施。
2.2 Sentinel的執(zhí)行流程
Sentinel的執(zhí)行流程主要分為以下幾個步驟:
- 資源埋點:通過
SphU.entry(resourceName)
和entry.exit()
方法對資源進行埋點。 - 規(guī)則判斷:當資源被訪問時,Sentinel會根據(jù)預(yù)設(shè)的規(guī)則進行判斷。
- 流量控制:如果觸發(fā)了規(guī)則條件,Sentinel會執(zhí)行相應(yīng)的流量控制措施,例如直接拒絕、排隊等待或預(yù)熱模式。
- 熔斷降級:對于響應(yīng)時間過長或異常比例過高的服務(wù),Sentinel會進行熔斷降級處理。
- 系統(tǒng)自適應(yīng)保護:當系統(tǒng)負載過高時,Sentinel會自動進行系統(tǒng)保護。
2.3 Sentinel的核心組件
Sentinel的核心組件主要包括:
- Sentinel核心庫:不依賴任何框架/庫,能夠運行于所有Java運行時環(huán)境,同時對Dubbo/Spring Cloud等框架也有較好的支持。
- Sentinel控制臺:基于Spring Boot開發(fā),打包后可以直接運行,不需要額外的Tomcat等應(yīng)用容器。
三、Sentinel基本功能點
3.1 流量控制
流量控制(flow control)是Sentinel最核心的功能之一,其原理是監(jiān)控應(yīng)用流量的QPS或并發(fā)線程數(shù)等指標,當達到指定的閾值時對流量進行控制,以避免被瞬時的流量高峰沖垮,從而保障應(yīng)用的高可用性。
流量控制主要有以下幾個維度:
基于QPS/并發(fā)數(shù)的流量控制:
- 并發(fā)數(shù)控制:用于保護業(yè)務(wù)線程池不被慢調(diào)用耗盡。
- QPS控制:當QPS超過某個閾值的時候,采取措施進行流量控制。
流量控制效果:
- 直接拒絕:默認的流量控制方式,當QPS超過任意規(guī)則的閾值后,新的請求就會被立即拒絕。
- Warm Up:預(yù)熱/冷啟動方式,讓通過的流量緩慢增加,在一定時間內(nèi)逐漸增加到閾值上限。
- 勻速排隊:嚴格控制請求通過的間隔時間,讓請求以均勻的速度通過,對應(yīng)的是漏桶算法。
基于調(diào)用關(guān)系的流量控制:
- 根據(jù)調(diào)用方來源進行流量控制。
- 支持針對不同的調(diào)用方設(shè)置不同的流控策略。
3.2 熔斷降級
熔斷降級(circuit breaking)是Sentinel的另一個重要功能,它用于當調(diào)用鏈路中某個資源出現(xiàn)不穩(wěn)定狀態(tài)時(例如調(diào)用超時或異常比例升高),對這個資源的調(diào)用進行限制,讓請求快速失敗,避免影響到其它的資源而導(dǎo)致級聯(lián)錯誤。
熔斷降級主要有以下幾個維度:
- 慢調(diào)用比例:當資源的響應(yīng)時間超過閾值(慢調(diào)用)的比例超過設(shè)定的比例閾值時,觸發(fā)熔斷。
- 異常比例/異常數(shù):當資源的異常比例或異常數(shù)超過閾值時,觸發(fā)熔斷。
- 恢復(fù)策略:熔斷觸發(fā)后,經(jīng)過一段時間(即熔斷超時時間),熔斷器會進入探測恢復(fù)狀態(tài),若接下來的一個請求處理成功,則結(jié)束熔斷,否則繼續(xù)熔斷。
3.3 熱點參數(shù)限流
熱點參數(shù)限流是一種更細粒度的流量控制,它允許用戶針對某個熱點參數(shù)進行限流,例如針對某個用戶ID限流。
熱點參數(shù)限流的特點:
- 可以針對某個參數(shù)的特定值單獨設(shè)置限流閾值。
- 支持多種參數(shù)類型,包括基本類型和字符串類型。
- 可以設(shè)置參數(shù)例外項,對特定的參數(shù)值進行不同的限流處理。
3.4 系統(tǒng)自適應(yīng)限流
系統(tǒng)自適應(yīng)限流從整體維度對應(yīng)用入口流量進行控制,結(jié)合應(yīng)用的Load、CPU使用率、總體平均RT、入口QPS和并發(fā)線程數(shù)等幾個維度的監(jiān)控指標,通過自適應(yīng)的流控策略,讓系統(tǒng)的入口流量和系統(tǒng)的負載達到一個平衡,讓系統(tǒng)盡可能跑在最大吞吐量的同時保證系統(tǒng)整體的穩(wěn)定性。
系統(tǒng)規(guī)則包含以下幾個重要的參數(shù):
- Load:當系統(tǒng)load1超過閾值,且系統(tǒng)當前的并發(fā)線程數(shù)超過系統(tǒng)容量時才會觸發(fā)系統(tǒng)保護。
- CPU使用率:當系統(tǒng)CPU使用率超過閾值即觸發(fā)系統(tǒng)保護。
- 平均RT:當單臺機器上所有入口流量的平均RT達到閾值即觸發(fā)系統(tǒng)保護。
- 并發(fā)線程數(shù):當單臺機器上所有入口流量的并發(fā)線程數(shù)達到閾值即觸發(fā)系統(tǒng)保護。
- 入口QPS:當單臺機器上所有入口流量的QPS達到閾值即觸發(fā)系統(tǒng)保護。
3.5 黑白名單控制
黑白名單控制根據(jù)資源的請求來源(origin)限制資源是否通過:
- 白名單:來源(origin)在白名單內(nèi)的請求才可通過。
- 黑名單:來源(origin)在黑名單內(nèi)的請求不允許通過。
3.6 實時監(jiān)控
Sentinel提供實時的監(jiān)控功能,用戶可以實時查看接入應(yīng)用的單臺機器秒級數(shù)據(jù),甚至500臺以下規(guī)模的集群的匯總運行情況。監(jiān)控數(shù)據(jù)包括:
- 通過的請求數(shù)(pass):一秒內(nèi)到來到的請求。
- 被阻止的請求數(shù)(blocked):一秒內(nèi)被流量控制的請求數(shù)量。
- 成功處理的請求數(shù)(success):一秒內(nèi)成功處理完的請求。
- 總請求數(shù)(total):一秒內(nèi)到來的請求以及被阻止的請求總和。
- 平均響應(yīng)時間(RT):一秒內(nèi)該資源的平均響應(yīng)時間。
- 異常數(shù)(exception):一秒內(nèi)業(yè)務(wù)本身異常的總和。
3.7 動態(tài)規(guī)則配置
Sentinel支持多種動態(tài)規(guī)則源,包括:
- 文件配置:規(guī)則存儲在文件中,定期輪詢文件獲取規(guī)則。
- Nacos配置中心:規(guī)則存儲在Nacos配置中心,通過監(jiān)聽配置變更事件即時獲取規(guī)則。
- ZooKeeper:規(guī)則存儲在ZooKeeper中,通過監(jiān)聽節(jié)點變更事件即時獲取規(guī)則。
- Apollo配置中心:規(guī)則存儲在Apollo配置中心,通過監(jiān)聽配置變更事件即時獲取規(guī)則。
- Redis:規(guī)則存儲在Redis中,通過定期輪詢獲取規(guī)則。
四、SpringBoot整合Sentinel完整案例
下面我們將通過一個完整的案例,演示如何在SpringBoot項目中整合Sentinel。
4.1 項目結(jié)構(gòu)
springcloud-sentinel ├── src │ └── main │ ├── java │ │ └── com.example │ │ ├── config │ │ │ └── SentinelConfig.java │ │ ├── controller │ │ │ └── TestSentinelController.java │ │ ├── service │ │ │ └── HelloService.java │ │ └── SentinelApplication.java │ └── resources │ └── application.properties └── pom.xml
4.2 Maven依賴配置
<?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"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>springboot-sentinel-demo</artifactId> <version>1.0-SNAPSHOT</version> <properties> <java.version>1.8</java.version> <spring-boot.version>2.6.3</spring-boot.version> <spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version> </properties> <dependencyManagement> <dependencies> <!-- Spring Boot 依賴管理 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- Spring Cloud Alibaba 依賴管理 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- Spring Boot Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Sentinel 依賴 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- Lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
4.3 應(yīng)用配置文件
# application.properties spring.application.name=sentinel-demo server.port=8080 # Sentinel 控制臺地址 spring.cloud.sentinel.transport.dashboard=localhost:8080 # 取消Sentinel控制臺懶加載 spring.cloud.sentinel.eager=true # 設(shè)置應(yīng)用與Sentinel控制臺的心跳間隔時間 spring.cloud.sentinel.transport.heartbeat-interval-ms=3000
4.4 Sentinel配置類
package com.example.config; import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Sentinel配置類 * 注冊SentinelResourceAspect,用于支持@SentinelResource注解 */ @Configuration public class SentinelConfig { @Bean public SentinelResourceAspect sentinelResourceAspect() { return new SentinelResourceAspect(); } }
4.5 服務(wù)類
package com.example.service; import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockException; import org.springframework.stereotype.Service; /** * 業(yè)務(wù)服務(wù)類 * 使用@SentinelResource注解定義資源點 */ @Service public class HelloService { /** * 定義一個資源點,指定blockHandler處理限流異常 * @param name 參數(shù) * @return 返回結(jié)果 */ @SentinelResource(value = "sayHello", blockHandler = "sayHelloExceptionHandler") public String sayHello(String name) { return "Hello, " + name; } /** * 定義一個資源點,同時指定blockHandler和fallback * blockHandler: 處理限流異常 * fallback: 處理業(yè)務(wù)異常 * @param name 參數(shù) * @return 返回結(jié)果 */ @SentinelResource(value = "circuitBreaker", fallback = "circuitBreakerFallback", blockHandler = "sayHelloExceptionHandler") public String circuitBreaker(String name) { // 模擬業(yè)務(wù)邏輯,當name為"test"時拋出異常 if ("test".equals(name)) { return "Hello, " + name; } throw new RuntimeException("發(fā)生異常"); } /** * 熔斷降級處理方法,處理業(yè)務(wù)異常 * @param name 參數(shù) * @return 降級返回結(jié)果 */ public String circuitBreakerFallback(String name) { return "服務(wù)異常,熔斷降級,請稍后重試!"; } /** * 限流降級處理方法,處理限流異常 * @param name 參數(shù) * @param ex 限流異常 * @return 限流返回結(jié)果 */ public String sayHelloExceptionHandler(String name, BlockException ex) { return "訪問過快,限流降級,請稍后重試!"; } }
4.6 控制器類
package com.example.controller; import com.example.service.HelloService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * 測試Sentinel的控制器 */ @RestController @RequestMapping("/sentinel") public class TestSentinelController { @Autowired private HelloService helloService; /** * 測試限流功能 * @param name 參數(shù) * @return 返回結(jié)果 */ @GetMapping("/hello") public String hello(@RequestParam("name") String name) { return helloService.sayHello(name); } /** * 測試熔斷功能 * @param name 參數(shù) * @return 返回結(jié)果 */ @GetMapping("/circuit") public String circuitBreaker(@RequestParam("name") String name) { return helloService.circuitBreaker(name); } }
4.7 應(yīng)用啟動類
package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Sentinel示例應(yīng)用啟動類 */ @SpringBootApplication public class SentinelApplication { public static void main(String[] args) { SpringApplication.run(SentinelApplication.class, args); } }
4.8 運行與測試
4.8.1 下載并啟動Sentinel控制臺
下載Sentinel控制臺jar包:
wget https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar
啟動Sentinel控制臺:
java -Dserver.port=8080 -jar sentinel-dashboard-1.8.6.jar
訪問Sentinel控制臺:
http://localhost:8080
默認用戶名和密碼都是:sentinel
4.8.2 啟動SpringBoot應(yīng)用
啟動應(yīng)用:
mvn spring-boot:run
測試限流功能:
http://localhost:8080/sentinel/hello?name=world
測試熔斷功能:
http://localhost:8080/sentinel/circuit?name=test
http://localhost:8080/sentinel/circuit?name=other
4.8.3 在Sentinel控制臺配置規(guī)則
登錄Sentinel控制臺后,可以看到應(yīng)用已經(jīng)注冊到控制臺
配置流控規(guī)則:
- 點擊"簇點鏈路",找到"sayHello"資源
- 點擊"流控"按鈕,設(shè)置QPS閾值為5
- 保存規(guī)則
配置熔斷規(guī)則:
- 點擊"簇點鏈路",找到"circuitBreaker"資源
- 點擊"降級"按鈕,設(shè)置異常比例閾值為0.5,時間窗口為10s
- 保存規(guī)則
測試規(guī)則效果:
- 快速刷新限流接口,當QPS超過5時,會觸發(fā)限流
- 多次訪問熔斷接口并傳入非"test"參數(shù),當異常比例超過50%時,會觸發(fā)熔斷
4.9 高級配置
4.9.1 持久化規(guī)則配置
Sentinel支持多種數(shù)據(jù)源來持久化規(guī)則配置,以下是使用文件配置的示例:
# 配置Sentinel規(guī)則持久化到文件 spring.cloud.sentinel.datasource.ds1.file.file=classpath:sentinel/flow-rule.json spring.cloud.sentinel.datasource.ds1.file.data-type=json spring.cloud.sentinel.datasource.ds1.file.rule-type=flow spring.cloud.sentinel.datasource.ds2.file.file=classpath:sentinel/degrade-rule.json spring.cloud.sentinel.datasource.ds2.file.data-type=json spring.cloud.sentinel.datasource.ds2.file.rule-type=degrade
4.9.2 Nacos配置中心持久化
# 配置Sentinel規(guī)則持久化到Nacos spring.cloud.sentinel.datasource.ds1.nacos.server-addr=localhost:8848 spring.cloud.sentinel.datasource.ds1.nacos.data-id=sentinel-flow-rules spring.cloud.sentinel.datasource.ds1.nacos.group-id=SENTINEL_GROUP spring.cloud.sentinel.datasource.ds1.nacos.data-type=json spring.cloud.sentinel.datasource.ds1.nacos.rule-type=flow spring.cloud.sentinel.datasource.ds2.nacos.server-addr=localhost:8848 spring.cloud.sentinel.datasource.ds2.nacos.data-id=sentinel-degrade-rules spring.cloud.sentinel.datasource.ds2.nacos.group-id=SENTINEL_GROUP spring.cloud.sentinel.datasource.ds2.nacos.data-type=json spring.cloud.sentinel.datasource.ds2.nacos.rule-type=degrade
4.9.3 自定義全局異常處理
package com.example.config; import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler; import com.alibaba.csp.sentinel.slots.block.BlockException; import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException; import com.alibaba.csp.sentinel.slots.block.flow.FlowException; import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException; import com.alibaba.csp.sentinel.slots.system.SystemBlockException; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; /** * 自定義Sentinel全局異常處理 */ @Configuration public class SentinelBlockExceptionHandler implements BlockExceptionHandler { @Override public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception { // 設(shè)置響應(yīng)類型 response.setStatus(429); response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.setCharacterEncoding("UTF-8"); Map<String, Object> result = new HashMap<>(); result.put("code", 429); result.put("success", false); if (e instanceof FlowException) { result.put("message", "請求被限流了"); } else if (e instanceof DegradeException) { result.put("message", "請求被降級了"); } else if (e instanceof ParamFlowException) { result.put("message", "熱點參數(shù)限流"); } else if (e instanceof SystemBlockException) { result.put("message", "系統(tǒng)規(guī)則限制"); } else if (e instanceof AuthorityException) { result.put("message", "授權(quán)規(guī)則不通過"); } else { result.put("message", "未知限流降級"); } // 返回JSON數(shù)據(jù) PrintWriter out = response.getWriter(); out.write(new ObjectMapper().writeValueAsString(result)); out.flush(); out.close(); } }
五、總結(jié)
本文詳細介紹了Sentinel的核心原理和基本功能點,包括流量控制、熔斷降級、熱點參數(shù)限流、系統(tǒng)自適應(yīng)限流等,并提供了一個完整的SpringBoot整合Sentinel的案例。
Sentinel作為一個面向分布式服務(wù)架構(gòu)的流量控制組件,在微服務(wù)架構(gòu)中扮演著重要的角色。它不僅提供了豐富的流量控制策略,還提供了實時的監(jiān)控功能,可以幫助開發(fā)者更好地了解服務(wù)的運行情況,及時發(fā)現(xiàn)和解決問題。
在實際應(yīng)用中,我們可以根據(jù)業(yè)務(wù)需求,靈活配置Sentinel的各種規(guī)則,以達到最佳的保護效果。同時,Sentinel還提供了多種規(guī)則持久化的方式,可以方便地將規(guī)則存儲到配置中心,實現(xiàn)規(guī)則的動態(tài)更新。
參考資料
到此這篇關(guān)于Sentinel原理與SpringBoot整合實戰(zhàn)案例講解的文章就介紹到這了,更多相關(guān)SpringBoot整合Sentinel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot?Validation提示信息國際化配置方式
這篇文章主要介紹了SpringBoot?Validation提示信息國際化配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02Java單例模式下的MongoDB數(shù)據(jù)庫操作工具類
這篇文章主要介紹了Java單例模式下的MongoDB數(shù)據(jù)庫操作工具類,結(jié)合實例形式分析了java基于單例模式下操作MongoDB數(shù)據(jù)庫相關(guān)連接、查詢、插入、刪除等操作封裝技巧,需要的朋友可以參考下2018-01-01SpringCloud通過MDC實現(xiàn)分布式鏈路追蹤
在DDD領(lǐng)域驅(qū)動設(shè)計中,我們使用SpringCloud來去實現(xiàn),但排查錯誤的時候,通常會想到Skywalking,但是引入一個新的服務(wù),增加了系統(tǒng)消耗和管理學(xué)習(xí)成本,對于大型項目比較適合,但是小的項目顯得太過臃腫了,所以本文介紹了SpringCloud通過MDC實現(xiàn)分布式鏈路追蹤2024-11-11java并發(fā)學(xué)習(xí)之BlockingQueue實現(xiàn)生產(chǎn)者消費者詳解
這篇文章主要介紹了java并發(fā)學(xué)習(xí)之BlockingQueue實現(xiàn)生產(chǎn)者消費者詳解,具有一定參考價值,需要的朋友可以了解下。2017-11-11Java 自旋鎖(spinlock)相關(guān)知識總結(jié)
這篇文章主要介紹了Java 自旋鎖(spinlock)相關(guān)知識總結(jié),幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2021-02-02