0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

ApiBoot Logging使用Spring Cloud Openfeign透?jìng)麈溌沸畔?/h1>

ApiBoot Logging可以無(wú)縫整合SpringCloud來(lái)采集請(qǐng)求日志,目前支持RestTemplate、Openfeign兩種方式,我們本章來(lái)講解下在使用Openfeign完成服務(wù)之間請(qǐng)求相互調(diào)用的一條鏈路請(qǐng)求日志是否可以都采集到。

搭建Eureka Server

我們先來(lái)搭建一個(gè)Eureka Server,請(qǐng)?jiān)L問(wèn)【搭建服務(wù)注冊(cè)中心Eureka Server】文章內(nèi)容查看具體搭建流程。

搭建Logging Admin

我們需要搭建一個(gè)Logging Admin用于接收Logging Client上報(bào)的請(qǐng)求日志,請(qǐng)?jiān)L問(wèn)【ApiBoot Logging整合SpringCloud Eureka負(fù)載均衡上報(bào)日志】查看具體的搭建流程。

我們本章來(lái)模擬提交訂單的業(yè)務(wù)邏輯,涉及到兩個(gè)服務(wù),分別是:商品服務(wù)訂單服務(wù),接下來(lái)我們需要來(lái)創(chuàng)建這兩個(gè)服務(wù)。

添加ApiBoot & SpringCloud統(tǒng)一版本

由于是采用Maven 多模塊項(xiàng)目,存在繼承關(guān)系,我們只需要在root模塊添加版本依賴即可,其他子模塊就可以直接使用,如下所示:

1.82.1.5.RELEASEGreenwich.SR3org.minbox.frameworkapi-boot-dependencies${api.boot.version}pomimportorg.springframework.cloudspring-cloud-dependencies${spring.cloud.version}pomimport

創(chuàng)建公共Openfeign接口定義

學(xué)習(xí)過(guò)Openfeign的同學(xué)應(yīng)該都知道,Openfeign可以繼承實(shí)現(xiàn),我們只需要?jiǎng)?chuàng)建一個(gè)公共的服務(wù)接口定義,在實(shí)現(xiàn)該接口的服務(wù)進(jìn)行業(yè)務(wù)實(shí)現(xiàn),在調(diào)用該接口的地方直接注入即可。
下面我們創(chuàng)建一個(gè)名為common-openfeign的公共依賴項(xiàng)目,pom.xml添加依賴如下所示:

org.springframework.bootspring-boot-starter-webtrueorg.springframework.cloudspring-cloud-starter-openfeigntrue

在提交訂單時(shí)我們簡(jiǎn)單模擬需要獲取商品的單價(jià),所以在common-openfeign項(xiàng)目?jī)?nèi)我們要提供一個(gè)查詢商品單價(jià)的服務(wù)接口,創(chuàng)建一個(gè)名為GoodClient的接口如下所示:

package org.minbox.chapter.common.openfeign;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 商品服務(wù)接口定義
 *
 * @author 恒宇少年
 */
@FeignClient(name = "good-service")
@RequestMapping(value = "/good")
public interface GoodClient {
    /**
     * 獲取商品價(jià)格
     *
     * @param goodId 商品編號(hào)
     * @return
     */
    @GetMapping(value = "/{goodId}")
    Double getGoodPrice(@PathVariable("goodId") Integer goodId);
}

注解解釋:

  • @FeignClientSpringCloud Openfeign提供的接口客戶端定義注解,通過(guò)value或者name來(lái)指定GoodClient訪問(wèn)的具體ServiceID,這里我們配置的value值為good-service項(xiàng)目spring.application.name配置參數(shù)ServiceID = spring.application.name)。
這樣當(dāng)我們通過(guò)注入GoodClient接口調(diào)用getGoodPrice方法時(shí),底層通過(guò)OpenfeignHttp代理訪問(wèn)good-service的對(duì)應(yīng)接口。

創(chuàng)建商品服務(wù)

下面我們?cè)賮?lái)創(chuàng)建一個(gè)名為good-serviceSpringBoot項(xiàng)目。

添加相關(guān)依賴

pom.xml項(xiàng)目配置文件內(nèi)添加如下依賴:

org.minbox.frameworkapi-boot-starter-loggingorg.springframework.bootspring-boot-starter-weborg.springframework.cloudspring-cloud-starter-netflix-eureka-clientorg.minbox.chaptercommon-openfeign0.0.1-SNAPSHOT

可以看到我們?cè)?code>good-service項(xiàng)目依賴內(nèi)添加了我們?cè)谏厦鎰?chuàng)建的common-openfeign依賴模塊,因?yàn)?code>GoodClient服務(wù)接口的實(shí)現(xiàn)是在good-service項(xiàng)目?jī)?nèi),我們需要添加common-openfeign依賴后創(chuàng)建對(duì)應(yīng)的XxxController并實(shí)現(xiàn)GoodClient接口完成對(duì)應(yīng)的業(yè)務(wù)邏輯實(shí)現(xiàn)。

商品業(yè)務(wù)實(shí)現(xiàn)

這里我們簡(jiǎn)單做個(gè)示例,將價(jià)格固定返回,實(shí)現(xiàn)GoodClient控制器如下所示:

package org.minbox.chapter.good.service;

import org.minbox.chapter.common.openfeign.GoodClient;
import org.springframework.web.bind.annotation.RestController;

/**
 * 商品服務(wù)接口實(shí)現(xiàn)
 *
 * @author 恒宇少年
 * @see GoodClient
 */
@RestController
public class GoodController implements GoodClient {
    @Override
    public Double getGoodPrice(Integer goodId) {
        if (goodId == 1) {
            return 15.6;
        }
        return 0D;
    }
}

注冊(cè)到Eureka Server

我們需要將good-service注冊(cè)到Eureka Server,修改application.yml配置文件如下所示:

# ServiceID
spring:
  application:
    name: good-service
# 端口號(hào)
server:
  port: 8082
# Eureka Config
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10000/eureka/
  instance:
    prefer-ip-address: true

配置上報(bào)的Logging Admin

我們需要將good-service的請(qǐng)求日志上報(bào)到Logging Admin,采用SpringCloud ServiceID的方式配置,修改application.yml配置文件如下所示:

api:
  boot:
    logging:
      # 控制臺(tái)打印日志
      show-console-log: true
      # 美化打印日志
      format-console-log-json: true
      # 配置Logging Admin 服務(wù)編號(hào)
      discovery:
        service-id: logging-admin

啟用Eureka Client & Logging

最后我們?cè)?code>XxxApplication入口類添加注解來(lái)啟用Eureka Client以及Logging Client,如下所示:

/**
 * 商品服務(wù)
 *
 * @author 恒宇少年
 */
@SpringBootApplication
@EnableLoggingClient
@EnableDiscoveryClient
public class GoodServiceApplication {
    /**
     * logger instance
     */
    static Logger logger = LoggerFactory.getLogger(GoodServiceApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(GoodServiceApplication.class, args);
        logger.info("{}服務(wù)啟動(dòng)成功.", "商品");
    }
}
至此我們的商品服務(wù)已經(jīng)準(zhǔn)備完成.

創(chuàng)建訂單服務(wù)

創(chuàng)建一個(gè)名為order-serviceSpringBoot項(xiàng)目(建議參考源碼,本章采用Maven多模塊創(chuàng)建)。

添加相關(guān)依賴

修改pom.xml添加相關(guān)依賴如下所示:

org.minbox.frameworkapi-boot-starter-loggingorg.springframework.bootspring-boot-starter-weborg.springframework.cloudspring-cloud-starter-netflix-eureka-clientorg.springframework.cloudspring-cloud-starter-openfeignorg.minbox.chaptercommon-openfeign0.0.1-SNAPSHOT

訂單業(yè)務(wù)實(shí)現(xiàn)

我們來(lái)模擬一個(gè)提交訂單的場(chǎng)景,創(chuàng)建一個(gè)名為OrderController的控制器,如下所示:

/**
 * 訂單控制器
 *
 * @author 恒宇少年
 */
@RestController
@RequestMapping(value = "/order")
public class OrderController {
    /**
     * 商品接口定義注入
     * {@link GoodClient}
     */
    @Autowired
    private GoodClient goodClient;

    @PostMapping
    public String submit(Integer goodId, Integer buyCount) {
        Double goodPrice = goodClient.getGoodPrice(goodId);
        Double orderAmount = goodPrice * buyCount;
        //...
        return "訂單提交成功,訂單總金額:" + orderAmount;
    }
}

注冊(cè)到Eureka Server

將我們創(chuàng)建的order-service注冊(cè)到Eureka Server,修改application.yml配置文件如下所示:

spring:
  application:
    name: order-service
server:
  port: 8081
# Eureka Config
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10000/eureka/
  instance:
    prefer-ip-address: true

配置上報(bào)的Logging Admin

我們需要將order-service的請(qǐng)求日志上報(bào)到Logging Admin,采用SpringCloud ServiceID的方式配置,修改application.yml配置文件如下所示:

api:
  boot:
    logging:
      # 控制臺(tái)打印日志
      show-console-log: true
      # 美化打印日志
      format-console-log-json: true
      # 配置Logging Admin 服務(wù)編號(hào)
      discovery:
        service-id: logging-admin

啟用Eureka Client & Logging

修改order-service入口類OrderServiceApplication,添加啟用Eureka ClientLogging Client的注解,如下所示:

/**
 * 訂單服務(wù)
 *
 * @author 恒宇少年
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableLoggingClient
@EnableFeignClients(basePackages = "org.minbox.chapter.common.openfeign")
public class OrderServiceApplication {
    /**
     * logger instance
     */
    static Logger logger = LoggerFactory.getLogger(OrderServiceApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
        logger.info("{}服務(wù)啟動(dòng)成功.", "");
    }
}

注解解釋:

  • @EnableFeignClients:該注解是Openfeign提供的啟用自動(dòng)掃描Client的配置,我們通過(guò)basePackages(基礎(chǔ)包名)的方式進(jìn)行配置掃描包下配置@FeignClient注解的接口,并為每個(gè)接口生成對(duì)應(yīng)的代理實(shí)現(xiàn)并添加到Spring IOC容器。

    org.minbox.chapter.common.openfeign包名在common-openfeign項(xiàng)目?jī)?nèi)。

運(yùn)行測(cè)試

依次啟動(dòng)項(xiàng)目,eureka-server > logging-admin > good-service > order-service。

通過(guò)curl命令訪問(wèn)order-service內(nèi)的提交訂單地址:/order,如下所示:

? ~ curl -X POST http://localhost:8081/order/?goodId/=1/&buyCount/=3
訂單提交成功,訂單總金額:46.8
可以看到我們已經(jīng)可以成功的獲取訂單的總金額,我們?cè)?code>/order請(qǐng)求方法內(nèi)調(diào)用good-service獲取商品的單價(jià)后計(jì)算得到訂單總金額。

測(cè)試點(diǎn):鏈路信息傳遞

我們通過(guò)控制臺(tái)輸出的日志信息來(lái)確認(rèn)下鏈路信息(traceId、spanId)的透?jìng)魇欠裾_。

收到order-service上報(bào)的日志

Receiving Service: 【order-service -> 127.0.0.1】, Request Log Report,Logging Content:[
    {
        "endTime":1573009439840,
        "httpStatus":200,
        "requestBody":"",
        "requestHeaders":{
            "host":"localhost:8081",
            "user-agent":"curl/7.64.1",
            "accept":"*/*"
        },
        "requestIp":"0:0:0:0:0:0:0:1",
        "requestMethod":"POST",
        "requestParam":"{/"buyCount/":/"3/",/"goodId/":/"1/"}",
        "requestUri":"/order",
        "responseBody":"訂單提交成功,訂單總金額:46.8",
        "responseHeaders":{},
        "serviceId":"order-service",
        "serviceIp":"127.0.0.1",
        "servicePort":"8081",
        "spanId":"241ef717-b0b3-4fcc-adae-b63ffd3dbbe4",
        "startTime":1573009439301,
        "timeConsuming":539,
        "traceId":"3e20cc72-c880-4575-90ed-d54a6b4fe555"
    }
]

收到good-service上報(bào)的日志

Receiving Service: 【good-service -> 127.0.0.1】, Request Log Report,Logging Content:[
    {
        "endTime":1573009439810,
        "httpStatus":200,
        "parentSpanId":"241ef717-b0b3-4fcc-adae-b63ffd3dbbe4",
        "requestBody":"",
        "requestHeaders":{
            "minbox-logging-x-parent-span-id":"241ef717-b0b3-4fcc-adae-b63ffd3dbbe4",
            "minbox-logging-x-trace-id":"3e20cc72-c880-4575-90ed-d54a6b4fe555",
            "host":"10.180.98.156:8082",
            "connection":"keep-alive",
            "accept":"*/*",
            "user-agent":"Java/1.8.0_211"
        },
        "requestIp":"10.180.98.156",
        "requestMethod":"GET",
        "requestParam":"{}",
        "requestUri":"/good/1",
        "responseBody":"15.6",
        "responseHeaders":{},
        "serviceId":"good-service",
        "serviceIp":"127.0.0.1",
        "servicePort":"8082",
        "spanId":"6339664e-097d-4a01-a734-935de52a7d44",
        "startTime":1573009439787,
        "timeConsuming":23,
        "traceId":"3e20cc72-c880-4575-90ed-d54a6b4fe555"
    }
]

結(jié)果分析:

  • 請(qǐng)求日志的入口為order-service所以并不存在parentSpanId(上級(jí)單元編號(hào)),而spanId(單元編號(hào))、traceId(鏈路編號(hào))也是新生成的。
  • 本次請(qǐng)求會(huì)經(jīng)過(guò)good-service服務(wù),因此parentSpanId則是order-service生成的spanIdtraceId同樣也是order-service生成的,透?jìng)鱄ttpHeader方式進(jìn)行傳遞,表示在同一條請(qǐng)求鏈路上。

敲黑板,劃重點(diǎn)

ApiBoot Logging支持使用Openfeign傳遞鏈路信息,內(nèi)部通過(guò)Openfeign攔截器實(shí)現(xiàn),源碼詳見(jiàn):org.minbox.framework.logging.client.http.openfeign.LoggingOpenFeignInterceptor

traceId(鏈路編號(hào))、parentSpanId(單元編號(hào))通過(guò)HttpHeader的形式傳遞到目標(biāo)訪問(wèn)服務(wù),服務(wù)通過(guò)請(qǐng)求日志攔截器進(jìn)行提取并設(shè)置鏈路綁定關(guān)系。

  • traceId傳遞時(shí)HttpHeader名稱為:minbox-logging-x-trace-id.
  • parentSpanId傳遞時(shí)HttpHeader名稱為:minbox-logging-x-parent-span-id
審核編輯 黃昊宇
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2967

    瀏覽量

    104763
  • spring
    +關(guān)注

    關(guān)注

    0

    文章

    340

    瀏覽量

    14344
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    811

    瀏覽量

    26580
  • 人臉識(shí)別
    +關(guān)注

    關(guān)注

    76

    文章

    4012

    瀏覽量

    81911
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    EDAS再升級(jí)!全面支持Spring Cloud應(yīng)用

    情況。除了微服務(wù)調(diào)用,EDAS還具備全的分布式跟蹤功能,模擬最真實(shí)的用戶場(chǎng)景,提前為系統(tǒng)創(chuàng)造可能面臨的大促流量高峰場(chǎng)景。在吞吐能力和響應(yīng)時(shí)間上,EDAS做了極大優(yōu)化。在同等測(cè)試條件下與Spring
    發(fā)表于 02-02 15:20

    Dubbo Cloud Native 之路的實(shí)踐與思考

    Native 基礎(chǔ)設(shè)施服務(wù)發(fā)現(xiàn)(Service Discovery )如何選擇EurekaConsulZookeeper負(fù)載均衡服務(wù)網(wǎng)關(guān)分布式配置服務(wù)熔斷跟蹤服務(wù)監(jiān)控Cloud Native 架構(gòu)選型
    發(fā)表于 07-05 16:05

    Spring Cloud Config公共配置解決方案

    Spring Cloud Config 多服務(wù)公共配置
    發(fā)表于 08-30 09:05

    使用Spring Cloud與Docker實(shí)戰(zhàn)微服務(wù)

    使用Spring Cloud與Docker實(shí)戰(zhàn)微服務(wù)
    發(fā)表于 09-09 08:31 ?7次下載
    使用<b class='flag-5'>Spring</b> <b class='flag-5'>Cloud</b>與Docker實(shí)戰(zhàn)微服務(wù)

    ApiBoot Logging Admin可視化界面管理日志教程

    ApiBoot Logging Admin支持界面可視化查看請(qǐng)求日志信息,初期版本支持查看上報(bào)日志的服務(wù)列表、最新的日志等功能,還可以整
    的頭像 發(fā)表于 12-10 22:03 ?501次閱讀

    ApiBoot Logging使用Rest Template信息

    在上一篇文章【ApiBoot Logging使用SpringCloud Openfeign
    的頭像 發(fā)表于 12-10 22:03 ?613次閱讀

    ApiBoot Logging整合Spring Cloud Eureka負(fù)載均衡上報(bào)日志

    ApiBoot Logging支持整合服務(wù)注冊(cè)中心(Eureka、Consul、Nacos Discovery、Zookeeper...)進(jìn)行上報(bào)請(qǐng)求日志,Logging Client會(huì)從服務(wù)注...
    的頭像 發(fā)表于 12-10 22:08 ?419次閱讀

    ApiBoot Logging忽略路徑不進(jìn)行采集日志的教程

    ApiBoot Logging支持排除指定路徑不參與日志的采集,當(dāng)我們的服務(wù)集成actuator時(shí),會(huì)不斷的重復(fù)調(diào)用內(nèi)置的路徑導(dǎo)致大量采集到一些無(wú)關(guān)業(yè)...
    的頭像 發(fā)表于 12-10 22:18 ?411次閱讀

    修改ApiBoot Logging日志采集前綴的教程

    ApiBoot Logging支持指定單個(gè)或者多個(gè)路徑的前綴進(jìn)行采集,也就是我們可以指定/user/**或者/order/**下的單個(gè)或者同時(shí)指定多個(gè)路徑進(jìn)行...
    的頭像 發(fā)表于 12-10 22:20 ?446次閱讀

    Spring Cloud Function基于Spring Boot的函數(shù)計(jì)算框架

    ./oschina_soft/spring-cloud-function.zip
    發(fā)表于 05-13 10:16 ?0次下載
    <b class='flag-5'>Spring</b> <b class='flag-5'>Cloud</b> Function基于<b class='flag-5'>Spring</b> Boot的函數(shù)計(jì)算框架

    RabbitRpc基于spring cloud的微服務(wù)rpc調(diào)用

    ./oschina_soft/gitee-spring-cloud-rabbitrpc.zip
    發(fā)表于 06-14 09:51 ?1次下載
    RabbitRpc基于<b class='flag-5'>spring</b> <b class='flag-5'>cloud</b>的微服務(wù)rpc調(diào)用

    Spring Cloud Tencent發(fā)布最新匹配版本!

    無(wú)論北極星還是 Spring Cloud Tencent 當(dāng)前都在積極的修復(fù) Bug、完善用戶體驗(yàn)、迭代新功能。所以 Spring Cloud Tencent 也第一時(shí)間適配了
    的頭像 發(fā)表于 12-09 15:34 ?1100次閱讀

    Spring Cloud 2022.0.0正式發(fā)布

    由于 Spring 現(xiàn)在提供了他們自己實(shí)現(xiàn)的接口 HTTP 客戶端解決方案,因此從 2022.0.0 開始,Spring Cloud OpenFeign 已到達(dá)特性完成狀態(tài)。這意味著
    的頭像 發(fā)表于 12-22 10:39 ?728次閱讀

    dubbo和spring cloud區(qū)別

    Dubbo和Spring Cloud是兩個(gè)非常流行的微服務(wù)框架,各有自己的特點(diǎn)和優(yōu)勢(shì)。在本文中,我們將詳細(xì)介紹Dubbo和Spring Cloud的區(qū)別。 1.架構(gòu)設(shè)計(jì): Dubbo是
    的頭像 發(fā)表于 12-04 14:47 ?1680次閱讀

    Spring Cloud Gateway網(wǎng)關(guān)框架

    Spring Cloud Gateway網(wǎng)關(guān)框架 本軟件微服務(wù)架構(gòu)中采用Spring Cloud Gateway網(wǎng)關(guān)控制框架,Spring
    的頭像 發(fā)表于 08-22 09:58 ?495次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Cloud</b> Gateway網(wǎng)關(guān)框架