在上一篇文章【ApiBoot Logging使用SpringCloud Openfeign透傳鏈路信息】中咱們詳細的講解了ApiBoot Logging
整合SpringCloud
經過Openfeign
進行透傳鏈路信息,包括traceId
(鏈路編號)、parentSpanId
(上級單元編號)等信息。ApiBoot Logging
不單單可使用Openfeign
傳遞鏈路信息,還支持RestTemplate
方式,本篇文章來詳細的講解下具體的使用方式。html
博客原文地址:http://blog.yuqiyu.com/apiboot-logging-using-resttemplate-transparent-traceid.htmljava
咱們須要搭建Logging Admin
服務,用於接收業務服務
上報的請求日誌信息,請參考【將ApiBoot Logging採集的日誌上報到Admin】文章內容.git
因爲本章採用是Maven 多模塊
的方式構建源碼,因此咱們只須要將ApiBoot
統一版本的依賴配置在root
項目的pom.xml
內,以下所示:web
<properties> <java.version>1.8</java.version> <!--ApiBoot版本號--> <api.boot.version>2.1.5.RELEASE</api.boot.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.minbox.framework</groupId> <artifactId>api-boot-dependencies</artifactId> <version>${api.boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
接下來咱們營造本篇文章的模擬場景
,查詢用戶基本信息時一併查詢出用戶的帳號餘額。spring
建立一個名爲account-service
的SpringBoot
項目。json
在項目pom.xml
配置文件內添加相關依賴,以下所示:api
<dependencies> <!--SpringBoot Web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--ApiBoot Logging--> <dependency> <groupId>org.minbox.framework</groupId> <artifactId>api-boot-starter-logging</artifactId> </dependency> </dependencies>
在application.yml
配置文件內添加請求日誌上報的Logging Admin
地址,以下所示:bash
spring: application: name: account-service server: port: 9090 api: boot: logging: # 控制檯打印請求日誌 show-console-log: true # 美化請求日誌 format-console-log-json: true # Logging Admin地址 admin: server-address: 127.0.0.1:8081
注意:server-address
配置參數不須要添加http://
前綴
添加完成依賴後咱們經過@EnableLoggingClient
註解來啓用ApiBoot Logging
,在AccountServiceApplication
類上添加以下所示:架構
/** * 帳戶服務 * * @author 恆宇少年 */ @SpringBootApplication @EnableLoggingClient public class AccountServiceApplication { /** * logger instance */ static Logger logger = LoggerFactory.getLogger(AccountServiceApplication.class); public static void main(String[] args) { SpringApplication.run(AccountServiceApplication.class, args); logger.info("{}服務啓動成功.", "帳戶"); } }
@EnableLoggingClient
註解就實例化部分ApiBoot Logging
內部所須要的類,將實例放置到Spring IOC
容器內。
咱們建立一個名爲AccountController
的控制器來提供查詢帳戶的餘額信息,代碼實現以下所示:app
/** * 帳戶服務實現 * * @author 恆宇少年 */ @RestController @RequestMapping(value = "/account") public class AccountController { /** * 示例,內存帳戶列表 */ static final HashMap<Integer, Double> ACCOUNTS = new HashMap() {{ put(1, 1233.22); put(2, 69269.22); }}; /** * 獲取指定帳戶的餘額 * * @param accountId * @return */ @GetMapping(value = "/{accountId}") public Double getBalance(@PathVariable("accountId") Integer accountId) { return ACCOUNTS.get(accountId); } }
至此咱們的帳戶服務已經編寫完成,下面咱們來編寫
用戶服務
。
咱們來建立一個名爲user-service
的SpringBoot
項目。
在項目pom.xml
配置文件內添加相關依賴,以下所示:
<dependencies> <!--SpringBoot Web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--ApiBoot Logging--> <dependency> <groupId>org.minbox.framework</groupId> <artifactId>api-boot-starter-logging</artifactId> </dependency> </dependencies>
本章咱們使用指定Logging Admin
地址的方式配置,修改application.yml
配置文件以下所示:
spring: application: name: user-service server: port: 9091 api: boot: logging: # 控制檯打印請求日誌 show-console-log: true # 美化請求日誌 format-console-log-json: true # Logging Admin地址 admin: server-address: 127.0.0.1:8081
添加完依賴後咱們須要在XxxApplication
入口類上添加@EnableLoggingClient
註解來啓用ApiBoot Logging
,以下所示:
/** * 用戶服務 * * @author 恆宇少年 */ @SpringBootApplication @EnableLoggingClient public class UserServiceApplication { /** * logger instance */ static Logger logger = LoggerFactory.getLogger(UserServiceApplication.class); public static void main(String[] args) { SpringApplication.run(UserServiceApplication.class, args); logger.info("{}服務啓動成功.", "用戶"); } }
在user-service
須要訪問帳戶服務
獲取當前用戶的餘額,因此咱們須要在user-service
內實例化RestTemplate
,這樣咱們才能夠經過RestTemplate
訪問獲取用戶帳戶餘額信息,咱們直接在UserServiceApplication
類內添加實例,以下所示:
/** * 實例化RestTemplate * * @return {@link RestTemplate} */ @Bean @ConditionalOnMissingBean public RestTemplate restTemplate() { return new RestTemplate(); }
註解解釋:
@ConditionalOnMissingBean
:這是SpringBoot
條件注入其中的一個註解,表示當IOC
容器內不存在RestTemplate
類型的實例時纔會去執行restTemplate()
方法建立對象。/** * 用戶基本信息控制器 * * @author 恆宇少年 */ @RestController @RequestMapping(value = "/user") public class UserController { /** * 示例,用戶列表 */ static final HashMap<Integer, User> USERS = new HashMap() {{ put(1, new User(1, "恆宇少年")); put(2, new User(2, "於起宇")); }}; /** * 注入RestTemplate */ @Autowired private RestTemplate restTemplate; /** * 獲取用戶基本信息 * * @param userId 用戶編號 * @return */ @GetMapping(value = "/{userId}") public User getUserInfo(@PathVariable("userId") Integer userId) { ResponseEntity<Double> responseEntity = restTemplate.getForEntity("http://localhost:9090/account/{accountId}", Double.class, userId); Double balance = responseEntity.getBody(); User user = USERS.get(userId); if (ObjectUtils.isEmpty(user)) { throw new RuntimeException("用戶:" + userId + ",不存在."); } user.setBalance(balance); return user; } @Data public static class User { private Integer id; private String name; private Double balance; public User(Integer id, String name) { this.id = id; this.name = name; } } }
咱們所須要的兩個服務都已經編寫完成,下面咱們來測試RestTemplate
是能夠透傳ApiBoot Logging
的鏈路信息?
依次啓動logging-admin
> user-service
> account-service
。
咱們使用curl
命令訪問user-service
提供的地址/user
,以下所示:
➜ ~ curl http://localhost:9091/user/1 {"id":1,"name":"恆宇少年","balance":1233.22}
下面我看來看下logging-admin
控制檯接收到的請求日誌。
接收user-service請求日誌
Receiving Service: 【user-service -> 127.0.0.1】, Request Log Report,Logging Content:[ { "endTime":1573032865311, "httpStatus":200, "requestBody":"", "requestHeaders":{ "host":"localhost:9091", "user-agent":"curl/7.64.1", "accept":"*/*" }, "requestIp":"0:0:0:0:0:0:0:1", "requestMethod":"GET", "requestParam":"{}", "requestUri":"/user/1", "responseBody":"{\"id\":1,\"name\":\"恆宇少年\",\"balance\":1233.22}", "responseHeaders":{}, "serviceId":"user-service", "serviceIp":"127.0.0.1", "servicePort":"9091", "spanId":"f8cff018-42d5-481f-98df-c19b7196b3c3", "startTime":1573032865130, "timeConsuming":181, "traceId":"16ad1dd4-beaa-4110-b4b7-fc7d952d9a57" } ]
接收account-service請求日誌
Receiving Service: 【account-service -> 127.0.0.1】, Request Log Report,Logging Content:[ { "endTime":1573032865309, "httpStatus":200, "parentSpanId":"f8cff018-42d5-481f-98df-c19b7196b3c3", "requestBody":"", "requestHeaders":{ "minbox-logging-x-parent-span-id":"f8cff018-42d5-481f-98df-c19b7196b3c3", "minbox-logging-x-trace-id":"16ad1dd4-beaa-4110-b4b7-fc7d952d9a57", "host":"localhost:9090", "connection":"keep-alive", "accept":"application/json, application/*+json", "user-agent":"Java/1.8.0_211" }, "requestIp":"127.0.0.1", "requestMethod":"GET", "requestParam":"{}", "requestUri":"/account/1", "responseBody":"1233.22", "responseHeaders":{}, "serviceId":"account-service", "serviceIp":"127.0.0.1", "servicePort":"9090", "spanId":"63b18b40-5718-431c-972f-78956ce78380", "startTime":1573032865307, "timeConsuming":2, "traceId":"16ad1dd4-beaa-4110-b4b7-fc7d952d9a57" } ]
user-service
服務內的/user
路徑時,由於是第一次訪問ApiBoot Logging
會主動建立traceId
(鏈路編號)、spanId
(單元編號),由於沒有上級單元
因此parentSpanId
爲null
.而經過查看account-service
服務上報的請求日誌時,能夠看到ApiBoot Logging
相關的鏈路信息是經過HttpHeader
的方式進行傳遞的
minbox-logging-x-trace-id
-> 鏈路編號
minbox-logging-x-parent-span-id
-> 上級單元編號
ApiBoot Logging
在內部自動化實現了RestTemplate
的攔截器配置,因此咱們只須要建立實例就能夠,而不須要主動去配置攔截器信息,具體源碼請訪問org.minbox.framework.logging.client.http.rest.LoggingRestTemplateInterceptor
查看。
無論你一次請求跨度幾個服務,均可以將請求入口
生成的鏈路信息
進行依次傳遞,而上下級關係則是根據parentSpanId
、spanId
進行綁定的。
若是您喜歡本篇文章請爲源碼倉庫點個Star
,謝謝!!!
本篇文章示例源碼能夠經過如下途徑獲取,目錄爲SpringBoot2.x/apiboot-logging-using-resttemplate-transparent-traceid
:
做者我的 博客
使用開源框架 ApiBoot 助你成爲Api接口服務架構師