spring-cloud微服務(wù)項(xiàng)目實(shí)戰(zhàn)(8)-log4j2集成sleuth

目的

  1. 在log4j2的基礎(chǔ)上集成sleuth名斟,進(jìn)行日志調(diào)用鏈跟蹤,進(jìn)行日志分析
  2. 改造項(xiàng)目接口砰盐,將原有/task/id,改成通過gateway-->client-->server的鏈子岩梳,方便測試,并同時(shí)改造原有g(shù)ateway(參考上篇文章zuul實(shí)戰(zhàn))的驗(yàn)簽方式

簡介

在Peter Deutsch的《The Eight Fallacies of Distributed Computing》中指出八個(gè)分布式計(jì)算的誤區(qū):

  • 網(wǎng)絡(luò)可靠
  • 延遲為零
  • 帶寬無限
  • 網(wǎng)絡(luò)絕對安全
  • 網(wǎng)絡(luò)拓?fù)洳粫?huì)變
  • 必須有一個(gè)管理員
  • 傳輸成本為零
  • 網(wǎng)絡(luò)同質(zhì)化

總結(jié)下上述問題淘捡,重點(diǎn)出在網(wǎng)路問題藕各。網(wǎng)絡(luò)常常十分脆弱,而我們部署了微服務(wù)作彤,系統(tǒng)變多,網(wǎng)絡(luò)傳輸增多竭讳,對我們排查問題提出了挑戰(zhàn)浙踢。sleuth的作用就是解決這個(gè)問題,進(jìn)行調(diào)用跟蹤洛波,形成調(diào)用鏈,方便快速找出問題所在蹬挤。
sleuth有幾個(gè)專業(yè)術(shù)語:

  1. span(跨度):一次調(diào)用鏈每個(gè)應(yīng)用的唯一id
  2. trace (跟蹤):一次調(diào)用鏈所有應(yīng)用共享的唯一id
  3. annotation (標(biāo)注):記錄事件,定義請求為止:
    • CS 客戶端發(fā)送請求
    • SR 服務(wù)端收到請求
    • SS 服務(wù)處理完請求倦零,發(fā)送返回信息
    • CR 客戶端收到請求

開工

  1. 添加sleuth依賴
     <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
     </dependency>
  1. log4j2配置文件中添加sleuth配置,暫時(shí)還用的STDOUT模式吨悍,打印到控制臺,方便測試育瓜,通過自定義sleuth參數(shù)[%X{X-B3-TraceId},%X{X-B3-SpanId},%X{X-B3-ParentSpanId},%X{X-Span-Export}]進(jìn)行打印,其中TraceId為此次調(diào)用鏈共享id爆雹,SpanId本應(yīng)用唯一id,ParentSpanId為上級應(yīng)用唯一id慧起,X-Span-Export是否是發(fā)送給Zipkin(后邊我們將會(huì)用到,本章不討論)
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">

    <Appenders>
        <File name="FileAppender" fileName="./log/logFile.log" append="true">
            <PatternLayout pattern="%d %-5p %c:%L [%t] - %m%n" />
        </File>

        <Console name="STDOUT" target="SYSTEM_OUT">
          //重點(diǎn)----自定義sleuth參數(shù)
             <PatternLayout pattern="%d [%X{X-B3-TraceId},%X{X-B3-SpanId},%X{X-B3-ParentSpanId},%X{X-Span-Export}] %-5p %c:%L [%t] - %m%n" />
        </Console>

        <RollingFile name="RollingFileInfo" fileName="./log/bee-client.log"
                     filePattern="./log/bee-client-gz/$${date:yyyy-MM}/bee-client-%d{yyyy-MM-dd}-%i.log.gz">
            <Filters>
                <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="%d %-5p %c:%L [%t] - %m%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="200 M"/>
            </Policies>
        </RollingFile>

    </Appenders>


    <Loggers>
        <Logger name="com.opensymphony.xwork2.ognl.OgnlValueStack" level="ERROR" />
        <Logger name="open.template" level="DEBUG" />
        <Logger name="org.springframework.cloud.netflix" level="DEBUG" />
        <Logger name="com.alisoft.xplatform.asf" level="WARN" />
        <Logger name="com.mbi" level="ERROR" />
        <Logger name="net.mlw" level="INFO" />
        <Logger name="java.sql" level="INFO" />
        <Logger name="org.hibernate.type" level="ERROR" />
        <Logger name="com.opensymphony.webwork" level="ERROR" />
        <Logger name="org.apache" level="INFO" />
        <Logger name="org.jgroups" level="WARN" />
        <Logger name="org.jboss.axis" level="INFO" />
        <Logger name="org.jboss.management" level="INFO" />
        <Logger name="org.apache.commons.httpclient" level="ERROR" />
        <Logger name="com.alibaba.dubbo" level="WARN" />
        <Logger name="com.mchange.v2.resourcepool" level="ERROR" />
        <Logger name="org.mybatis.spring" level="ERROR" />
        <Logger name="org.apache.ibatis" level="ERROR" />



        <Root level="INFO"><!-- 缺省日志級別,如果package有定制級別,則按package的定制級別走灿意,即使package級別更低 -->
            <AppenderRef ref="STDOUT" />
            <!--<AppenderRef ref="FileAppender" />-->
            <!--<AppenderRef ref="RollingFileInfo" />-->
        </Root>

    </Loggers>
</Configuration>

  1. 改造gateway、udm-client缤剧、udm-server服務(wù),同樣的方法荒辕,集成sleuth,改造日志配置,在gateway路由規(guī)則中添加udm-client配置抵窒,進(jìn)行鏈?zhǔn)綔y試
zuul:
#配置zuul統(tǒng)一前綴
  prefix: /api
#禁止所有eureka服務(wù)通過服務(wù)名直接訪問
  ignored-services:
    "*"
  routes:
#將微服務(wù)需要暴露服務(wù)進(jìn)行路由映射
    udm-server: /udm/**
    udm-client: /udc/**
  1. 改造gateway驗(yàn)簽,暫時(shí)替換為md5方式削茁,首先在commons中添加md5工具類
public class Md5Sign {

    public static String sign(String s) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] bytes = md.digest(s.getBytes("utf-8"));
            return toHex(bytes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    private static String toHex(byte[] bytes) {
        final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
        StringBuilder ret = new StringBuilder(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            ret.append(HEX_DIGITS[(bytes[i] >> 4) & 0x0f]);
            ret.append(HEX_DIGITS[bytes[i] & 0x0f]);
        }
        return ret.toString();
    }

   public static void main(String[] args) {
        StringBuffer stringBuffer=new StringBuffer();
        stringBuffer.append("ddd");
        stringBuffer.append("sdfadflakjsfd;aljfda;dkfja;dfk");
        String sign = sign(stringBuffer.toString());
        System.out.println(sign);
    }
}

然后修改gateway項(xiàng)目中添加feign依賴,用于調(diào)用獲取用戶信息方法茧跋,添加對應(yīng)service

//添加pom依賴
  <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
  </dependency>
......
//啟動(dòng)類添加feign掃包
@SpringBootApplication
@EnableZuulProxy
@EnableFeignClients(basePackages = "open.template.work.gateway.service")
public class GatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }

}
......
//添加接口service
@FeignClient(name = CloudServerDirectory.UDM_SERVER)
public interface AuthorizationService {

    /**
     * 調(diào)用獲取用戶密鑰
     * @param appKey
     * @return
     */
    @RequestMapping("/user/key")
    String getUserKey(String appKey);

}

最后在AuthorizationFilter中注入此AuthorizationService圃阳,并修改run方法

   @Override
    public Object run() {
        RequestContext currentContext = RequestContext.getCurrentContext(); // 獲取當(dāng)前請求的上下文
        Map<String, Object> params = null;
        try {
            //1.獲取請求參數(shù),支持json格式數(shù)據(jù)捍岳,通過inputstream解析數(shù)據(jù)
            try {
                params = HttpParser.requestJsonParser(currentContext.getRequest().getInputStream());

            } catch (IOException e) {
                throw new BaseTemplateException(ExceptionCodeEnum.Z88888);
            }

            LOGGER.info("獲取授權(quán)參數(shù)data={}", params);

            //2.通過md5驗(yàn)簽,生產(chǎn)環(huán)境可以根據(jù)需求調(diào)整更復(fù)雜的算法锣夹,為了測試簡單暫時(shí)通過客戶端的treemap進(jìn)行排序,將所有參數(shù)生成字符串银萍,然后拼接用戶密鑰
            //生成md5作為簽名
            if (params.get("appKey") != null) {
                String key = authorizationService.getUserKey(params.get("appKey").toString());
                if (StringUtils.isEmpty(key)) {
                    throw new BaseTemplateException(ExceptionCodeEnum.Z88887);
                }

                Object sign = params.get("sign");
                if (sign == null) {
                    throw new BaseTemplateException(ExceptionCodeEnum.Z88888);
                }

                StringBuffer stringBuffer = new StringBuffer();
                Set<String> paramsSet = params.keySet();
                for (String param : paramsSet) {
                    if (!param.equals("sign")) {
                        stringBuffer.append(params.get(param));
                    }
                }
                //本地加簽
                String localSign = Md5Sign.sign(stringBuffer.append(key).toString());
                if (!localSign.equals(sign)) {
                    throw new BaseTemplateException(ExceptionCodeEnum.Z88888);
                }

            }
        } catch (BaseTemplateException e) {
            currentContext.setSendZuulResponse(false);
            currentContext.setResponseStatusCode(200);
            currentContext.setResponseBody("{\"result \":\""+e.getMessage()+"\"}");
            currentContext.getResponse().setContentType("text/html;charset=UTF-8");
        }

        return null;

    }
  1. udm-server添加模擬獲取用戶密鑰信息接口
@RestController
public class UserApi {

    /**
     * 根據(jù)appKey獲取用戶密鑰
     * @param appKey
     * @return
     */
    @RequestMapping("/user/key")
    public String getUserKey(String appKey){
        return "sdfadflakjsfd;aljfda;dkfja;dfk";
    }
}
  1. 重啟相應(yīng)服務(wù)贴唇,通過curl模擬json格式post請求(因?yàn)閰?shù)中有對象參數(shù),索所以需要requestBody注解戳气,必須post的請求,其中sign參數(shù)通過md5多工具類生成),查看日志
    curl -H "Content-Type:application/json" -X POST --data '{"appKey":"ddd","sign":"6CBC57C961FCA12D89FB724400E87326"}' http://localhost:8061/api/udm/task/get
1.gateway日志
2. udm-server獲取用戶信息日志
3.udm-client調(diào)用日志
4. udm-server接受udm-client請求日志

完工麻捻!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市贸毕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌明棍,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件署拟,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)心包,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蟹腾,“玉大人,你說我怎么就攤上這事娃殖。” “怎么了炉爆?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長芬首。 經(jīng)常有香客問我,道長郁稍,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任耀怜,我火速辦了婚禮,結(jié)果婚禮上财破,老公的妹妹穿的比我還像新娘。我一直安慰自己狈究,他們只是感情好盏求,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布亿眠。 她就那樣靜靜地躺著,像睡著了一般纳像。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上竟趾,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天,我揣著相機(jī)與錄音岔帽,去河邊找鬼。 笑死犀勒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贾费。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼押桃,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了唱凯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤波丰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后掰烟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡纫骑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年九孩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片躺彬。...
    茶點(diǎn)故事閱讀 39,991評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡梅惯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出铣减,到底是詐尸還是另有隱情,我是刑警寧澤葫哗,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站劣针,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏亿扁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一魏烫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧哄褒,春花似錦煌张、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽档玻。三九已至,卻和暖如春误趴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凉当。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留看杭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓楼雹,卻偏偏與公主長得像尖阔,于是被迫代替她去往敵國和親榨咐。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容