ApiBoot Logging使用RestTemplate透傳鏈路資訊
在上一篇文章【ApiBoot Logging使用SpringCloud Openfeign透傳鏈路資訊】中我們詳細的講解了ApiBoot Logging
整合SpringCloud
通過Openfeign
進行透傳鏈路資訊,包括traceId
(鏈路編號)、parentSpanId
(上級單元編號)等資訊。
ApiBoot Logging
不僅僅可以使用Openfeign
傳遞鏈路資訊,還支援RestTemplate
方式,本篇文章來詳細的講解下具體的使用方式。
部落格原文地址:blog.yuqiyu.com/apiboot-log…
搭建Logging Admin
我們需要搭建Logging Admin
服務,用於接收業務服務
新增ApiBoot統一版本
由於本章採用是Maven 多模組
的方式構建原始碼,所以我們只需要將ApiBoot
統一版本的依賴配置在root
專案的pom.xml
內,如下所示:
<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>
複製程式碼
接下來我們營造本篇文章的模擬場景
,查詢使用者基本資訊時一併查詢出使用者的賬號餘額。
建立賬戶服務
建立一個名為account-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
配置檔案內新增請求日誌上報的Logging Admin
地址,如下所示:
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://
字首
啟用Logging Client
新增完成依賴後我們通過@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
的控制器來提供查詢賬戶的餘額資訊,程式碼實現如下所示:
/**
* 賬戶服務實現
*
* @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
本章我們使用指定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
複製程式碼
啟用Logging Client
新增完依賴後我們需要在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,"使用者");
}
}
複製程式碼
例項化RestTemplate物件
在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,"parentSpanId":"f8cff018-42d5-481f-98df-c19b7196b3c3","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","requestUri":"/account/1","responseBody":"1233.22","serviceId":"account-service","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
:
- Gitee:gitee.com/hengboy/spr…