Spring Cloud Sleuth進階實戰

為什么需要Spring Cloud Sleuth

微服務架構是一個分布式架構,它按業務劃分服務單元,一個分布式系統往往有很多個服務單元。由于服務單元數量眾多,業務的復雜性,如果出現了錯誤和異常,很難去定位。主要體現在,一個請求可能需要調用很多個服務,而內部服務的調用復雜性,決定了問題難以定位。所以微服務架構中,必須實現分布式鏈路追蹤,去跟進一個請求到底有哪些服務參與,參與的順序又是怎樣的,從而達到每個請求的步驟清晰可見,出了問題,很快定位。

舉個例子,在微服務系統中,一個來自用戶的請求,請求先達到前端A(如前端界面),然后通過遠程調用,達到系統的中間件B、C(如負載均衡、網關等),最后達到后端服務D、E,后端經過一系列的業務邏輯計算最后將數據返回給用戶。對于這樣一個請求,經歷了這么多個服務,怎么樣將它的請求過程的數據記錄下來呢?這就需要用到服務鏈路追蹤。

Google開源的 Dapper鏈路追蹤組件,并在2010年發表了論文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,這篇文章是業內實現鏈路追蹤的標桿和理論基礎,具有非常大的參考價值。?
目前,鏈路追蹤組件有Google的Dapper,Twitter 的Zipkin,以及阿里的Eagleeye (鷹眼)等,它們都是非常優秀的鏈路追蹤開源組件。

本文主要講述如何在Spring Cloud Sleuth中集成Zipkin。在Spring Cloud Sleuth中集成Zipkin非常的簡單,只需要引入相應的依賴和做相關的配置即可。

基本術語

Spring Cloud Sleuth采用的是Google的開源項目Dapper的專業術語。

  • Span:基本工作單元,發送一個遠程調度任務 就會產生一個Span,Span是一個64位ID唯一標識的,Trace是用另一個64位ID唯一標識的,Span還有其他數據信息,比如摘要、時間戳事件、Span的ID、以及進度ID。
  • Trace:一系列Span組成的一個樹狀結構。請求一個微服務系統的API接口,這個API接口,需要調用多個微服務,調用每個微服務都會產生一個新的Span,所有由這個請求產生的Span組成了這個Trace。
  • Annotation:用來及時記錄一個事件的,一些核心注解用來定義一個請求的開始和結束 。這些注解包括以下:?
    • cs - Client Sent -客戶端發送一個請求,這個注解描述了這個Span的開始
    • sr - Server Received -服務端獲得請求并準備開始處理它,如果將其sr減去cs時間戳便可得到網絡傳輸的時間。
    • ss - Server Sent (服務端發送響應)–該注解表明請求處理的完成(當請求返回客戶端),如果ss的時間戳減去sr時間戳,就可以得到服務器請求的時間。
    • cr - Client Received (客戶端接收響應)-此時Span的結束,如果cr的時間戳減去cs時間戳便可以得到整個請求所消耗的時間。

案例實戰

本文案例一共四個工程采用多Module形式。需要新建一個主Maven工程,主要指定了Spring Boot的版本為1.5.3,Spring Cloud版本為Dalston.RELEASE。包含了eureka-server工程,作為服務注冊中心,eureka-server的創建過程這里不重復;zipkin-server作為鏈路追蹤服務中心,負責存儲鏈路數據;gateway-service作為服務網關工程,負責請求的轉發,同時它也作為鏈路追蹤客戶端,負責產生數據,并上傳給zipkin-service;user-service為一個應用服務,對外暴露API接口,同時它也作為鏈路追蹤客戶端,負責產生數據。

構建zipkin-server工程

新建一個Module工程,取名為zipkin-server,其pom文件繼承了主Maven工程的pom文件;作為Eureka Client,引入Eureka的起步依賴spring-cloud-starter-eureka,引入zipkin-server依賴,以及zipkin-autoconfigure-ui依賴,后兩個依賴提供了Zipkin的功能和Zipkin界面展示的功能。代碼如下:

<parent><groupId>com.forezp</groupId><artifactId>sleuth</artifactId><version>0.0.1-SNAPSHOT</version></parent><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId></dependency><dependency><groupId>io.zipkin.java</groupId><artifactId>zipkin-server</artifactId></dependency><dependency><groupId>io.zipkin.java</groupId><artifactId>zipkin-autoconfigure-ui</artifactId></dependency></dependencies>

在程序的啟動類ZipkinServiceApplication加上@EnableZipkinServer開啟ZipkinServer的功能,加上@EnableEurekaClient注解,啟動Eureka Client。代碼如下:

@SpringBootApplication
@EnableEurekaClient
@EnableZipkinServer
public class ZipkinServerApplication {public static void main(String[] args) {SpringApplication.run(ZipkinServerApplication.class, args);}
}

在配置文件application.yml文件,指定程序名為zipkin-server,端口為9411,服務注冊地址為http://localhost:8761/eureka/。

eureka:client:serviceUrl:defaultZone: http://localhost:8761/eureka/
server:port: 9411
spring:application:name: zipkin-server

構建user-service

在主Maven工程下建一個Module工程,取名為user-service,作為應用服務,對外暴露API接口。pom文件繼承了主Maven工程的pom文件,并引入了Eureka的起步依賴spring-cloud-starter-eureka,Web起步依賴spring-boot-starter-web,Zipkin的起步依賴spring-cloud-starter-zipkin,代碼如下:

    <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zipkin</artifactId><version>RELEASE</version></dependency></dependencies>

在配置文件applicatiom.yml,指定了程序名為user-service,端口為8762,服務注冊地址為http://localhost:8761/eureka/,Zipkin Server地址為http://localhost:9411。spring.sleuth.sampler.percentage為1.0,即100%的概率將鏈路的數據上傳給Zipkin Server,在默認的情況下,該值為0.1,代碼如下:

eureka:client:serviceUrl:defaultZone: http://localhost:8761/eureka/
server:port: 8762
spring:application:name: user-servicezipkin:base-url: http://localhost:9411sleuth:sampler:percentage: 1.0

在UserController類建一個“/user/hi”的API接口,對外提供服務,代碼如下:

@RestController
@RequestMapping("/user")
public class UserController {@GetMapping("/hi")public String hi(){return "I'm forezp";}
}

最后作為Eureka Client,需要在程序的啟動類UserServiceApplication加上@EnableEurekaClient注解。

構建gateway-service

新建一個名為gateway-service工程,這個工程作為服務網關,將請求轉發到user-service,作為Zipkin客戶端,需要將鏈路數據上傳給Zipkin Server,同時它也作為Eureka Client。它在pom文件除了需要繼承主Maven工程的 pom,還需引入的依賴如下:

<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zuul</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zipkin</artifactId><version>RELEASE</version></dependency></dependencies>

在application.yml文件,配置程序名為gateway-service,端口為5000,服務注冊地址為http://localhost:8761/eureka/,Zipkin Server地址為http://localhost:9411,以“/user-api/**”開頭的Uri請求,轉發到服務名為 user-service的服務。配置代碼如下:

eureka:client:serviceUrl:defaultZone: http://localhost:8761/eureka/server:port: 5000
spring:application:name: gateway-servicesleuth:sampler:percentage: 1.0zipkin:base-url: http://localhost:9411zuul:routes:api-a:path: /user-api/**serviceId: user-service

在程序的啟動類GatewayServiceApplication,加上@EnableEurekaClient注解開啟Eureka Client,加上@EnableZuulProxy注解,開啟Zuul代理功能。代碼如下:

@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class GatewayServiceApplication {public static void main(String[] args) {SpringApplication.run(GatewayServiceApplication.class, args);}
}

項目演示

完整的項目搭建完畢,依次啟動eureka-server、zipkin-server、user-service、gateway-service。在瀏覽器上訪問http://localhost:5000/user-api/user/hi,瀏覽器顯示:

I’m forezp

訪問http://localhost:9411,即訪問Zipkin的展示界面,界面顯示如圖1所示:

image.png

這個界面主要用來查找服務的調用情況,可以根據服務名、開始時間、結束時間、請求消耗的時間等條件來查找。點擊“Find Trackes”按鈕,界面如圖所示。從圖可知服務的調用情況,比如服務調用時間、服務的消耗時間,服務調用的鏈路情況。

image.png

點擊Dependences按鈕,可以查看服務的依賴關系,在本案例中,gateway-service將請求轉發到了user-service,它們的依賴關系如圖:

image.png

怎么在鏈路數據中添加自定義數據

現在需要實現這樣一個功能,需要在鏈路數據中加上操作人。這需要在gateway-service上實現。建一個ZuulFilter過濾器,它的類型為“post”,order為900,開啟攔截。在攔截邏輯方法里,通過Tracer的addTag方法加上自定義的數據,比如本案例中加入了鏈路的操作人。另外也可以在這個過濾器中獲取當前鏈路的traceId信息,traceId作為鏈路數據的唯一標識,可以存儲在log日志中,方便后續查找。

@Component
public class LoggerFilter extends ZuulFilter {@AutowiredTracer tracer;@Overridepublic String filterType() {return FilterConstants.POST_TYPE;}@Overridepublic int filterOrder() {return 900;}@Overridepublic boolean shouldFilter() {return true;}@Overridepublic Object run() {tracer.addTag("operator","forezp");System.out.print(tracer.getCurrentSpan().traceIdString());return null;}
}

使用spring-cloud-starter-stream-rabbit進行鏈路通訊

在上述的案例中,最終gateway-service收集的數據,是通過Http上傳給zip-server的,在Spring Cloud Sleuth中支持消息組件來通訊的,在這一小節使用RabbitMQ來通訊。首先來改造zipkin-server,在pom文件將zipkin-server的依賴去掉,加上spring-cloud-sleuth-zipkin-stream和spring-cloud-starter-stream-rabbit,代碼如下:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-sleuth-zipkin-stream</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-stream-rabbit</artifactId></dependency>

在application.yml配置上RabbitMQ的配置,包括host、端口、用戶名、密碼,如下:

spring:rabbitmq:host: localhostport: 5672username: guestpassword: guest

在程序的啟動類ZipkinServerApplication上@EnableZipkinStreamServer注解,開啟ZipkinStreamServer。代碼如下:

@SpringBootApplication
@EnableEurekaClient
@EnableZipkinStreamServer
public class ZipkinServerApplication {public static void main(String[] args) {SpringApplication.run(ZipkinServerApplication.class, args);}
}

現在來改造下Zipkin Client(包括gateway-service、user-service),在pom文件中將spring-cloud-starter-zipkin以來改為spring-cloud-sleuth-zipkin-stream和spring-cloud-starter-stream-rabbit,代碼如下:


<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-sleuth-zipkin-stream</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-stream-rabbit</artifactId></dependency>

同時在applicayion.yml文件加上RabbitMQ的配置,同zipkin-server工程。

這樣,就將鏈路的上傳數據從Http改了為用消息代組件RabbitMQ。

將鏈路數據存儲在Mysql數據庫

在上述的例子中,Zipkin Server是將數據存儲在內存中,一旦程序重啟,之前的鏈路數據全部丟失,那么怎么將鏈路數據存儲起來呢?Zipkin支持Mysql、Elasticsearch、Cassandra存儲。這一小節講述用Mysql存儲,下一節講述用Elasticsearch存儲。

首先,在zipkin-server工程加上Mysql的連接依賴mysql-connector-java,JDBC的起步依賴spring-boot-starter-jdbc,代碼如下:

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency>

在配置文件application.yml加上數據源的配置,包括數據庫的Url、用戶名、密碼、連接驅動,另外需要配置zipkin.storage.type為mysql,代碼如下:

spring:datasource:url: jdbc:mysql://localhost:3306/spring-cloud-zipkin?useUnicode=true&characterEncoding=utf8&useSSL=falseusername: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driver
zipkin:storage:type: mysql

另外需要在Mysql數據庫中初始化數據庫腳本,數據庫腳本地址:https://github.com/openzipkin/zipkin/blob/master/zipkin-storage/mysql/src/main/resources/mysql.sql

CREATE TABLE IF NOT EXISTS zipkin_spans (`trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',`trace_id` BIGINT NOT NULL,`id` BIGINT NOT NULL,`name` VARCHAR(255) NOT NULL,`parent_id` BIGINT,`debug` BIT(1),`start_ts` BIGINT COMMENT 'Span.timestamp(): epoch micros used for endTs query and to implement TTL',`duration` BIGINT COMMENT 'Span.duration(): micros used for minDuration and maxDuration query'
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;ALTER TABLE zipkin_spans ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `id`) COMMENT 'ignore insert on duplicate';
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`, `id`) COMMENT 'for joining with zipkin_annotations';
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTracesByIds';
ALTER TABLE zipkin_spans ADD INDEX(`name`) COMMENT 'for getTraces and getSpanNames';
ALTER TABLE zipkin_spans ADD INDEX(`start_ts`) COMMENT 'for getTraces ordering and range';CREATE TABLE IF NOT EXISTS zipkin_annotations (`trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',`trace_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.trace_id',`span_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.id',`a_key` VARCHAR(255) NOT NULL COMMENT 'BinaryAnnotation.key or Annotation.value if type == -1',`a_value` BLOB COMMENT 'BinaryAnnotation.value(), which must be smaller than 64KB',`a_type` INT NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation',`a_timestamp` BIGINT COMMENT 'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp',`endpoint_ipv4` INT COMMENT 'Null when Binary/Annotation.endpoint is null',`endpoint_ipv6` BINARY(16) COMMENT 'Null when Binary/Annotation.endpoint is null, or no IPv6 address',`endpoint_port` SMALLINT COMMENT 'Null when Binary/Annotation.endpoint is null',`endpoint_service_name` VARCHAR(255) COMMENT 'Null when Binary/Annotation.endpoint is null'
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;ALTER TABLE zipkin_annotations ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) COMMENT 'Ignore insert on duplicate';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`, `span_id`) COMMENT 'for joining with zipkin_spans';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTraces/ByIds';
ALTER TABLE zipkin_annotations ADD INDEX(`endpoint_service_name`) COMMENT 'for getTraces and getServiceNames';
ALTER TABLE zipkin_annotations ADD INDEX(`a_type`) COMMENT 'for getTraces';
ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id`, `span_id`, `a_key`) COMMENT 'for dependencies job';CREATE TABLE IF NOT EXISTS zipkin_dependencies (`day` DATE NOT NULL,`parent` VARCHAR(255) NOT NULL,`child` VARCHAR(255) NOT NULL,`call_count` BIGINT,`error_count` BIGINT
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;ALTER TABLE zipkin_dependencies ADD UNIQUE KEY(`day`, `parent`, `child`);

將鏈路數據存儲在ElasticSearch

使用Mysql存儲鏈路數據,在并發高的情況下,顯然不合理,這時可以選擇使用ElasticSearch存儲。讀者需要自行安裝ElasticSearch、Kibana(下一小節使用),下載地址為https://www.elastic.co/products/elasticsearch。安裝完成后并啟動它們,其中ElasticSearch的默認端口為9200,Kibana的端口為5601。

安裝的過程可以參考我的這篇文章:http://blog.csdn.net/forezp/article/details/71189836

本小節的案例在上上小節的案例的基礎上進行改造。首先在pom文件,加上zipkin的依賴和zipkin-autoconfigure-storage-elasticsearch-http的依賴,代碼如下:

<dependency><groupId>io.zipkin.java</groupId><artifactId>zipkin</artifactId><version>1.28.0</version></dependency><dependency><groupId>io.zipkin.java</groupId><artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId><version>1.28.0</version></dependency>

在application.yml文件加上Zipkin的配置,配置了zipkin的存儲類型為elasticsearch,使用的StorageComponent為elasticsearch。然后需要配置elasticsearch,包括hosts,可以配置多個,用“,”隔開;index為zipkin等,具體配置如下:


zipkin:storage:type: elasticsearchStorageComponent: elasticsearchelasticsearch:cluster: elasticsearchmax-requests: 30index: zipkinindex-shards: 3index-replicas: 1hosts: localhost:9200

在kibana上展示

上一小節講述了如何將鏈路數據存儲在ElasticSearch,ElasticSearch可以和Kibana結合,將鏈路數據展示在 Kibana上。安裝完Kibana,并啟動,它默認會向本地的9200端口的ElasticSearch讀取數據,它默認的端口為5601。訪問http://localhost:5601,顯示的界面如下:

image.png

在上述的界面點擊”Management”按鈕,然后點擊“Add New”,添加一個index,在上節我們在ElasticSearch中寫入鏈路數據的index配置為“zipkin”,那么在界面填寫為“zipkin-*”,點擊“Create”按鈕。

image.png

創建完index之后,點擊Discover,就可以在界面上展示鏈路數據了。

image.png

采用Http的方式傳輸鏈路數據怎么存在mysql中(補充)

在我的項目中,采用rabbitmq傳輸,并存儲在mysql中,遇到了程序啟動慢的問題,遂決定改成http傳輸鏈路數據,但采用http 傳輸鏈路是我之前沒有講解過的,于是做下補充。

源碼工程在:https://github.com/forezp/SpringCloudLearning/tree/master/chapter-sleuth-mysql

首先在zipkin-server 的pom文件中,加上以下的依賴:

 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId></dependency><dependency><groupId>io.zipkin.java</groupId><artifactId>zipkin-server</artifactId><version>1.19.0</version></dependency><dependency><groupId>io.zipkin.java</groupId><artifactId>zipkin-storage-mysql</artifactId><version>1.19.0</version></dependency><dependency><groupId>io.zipkin.java</groupId><artifactId>zipkin-autoconfigure-ui</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency>

工程的配置文件bootstrap.yml:

eureka:client:serviceUrl:defaultZone: http://localhost:8761/eureka/
server:port: 9411
spring:application:name: zipkin-serversleuth:sampler:percentage: 1.0enabled: falsedatasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/spring-cloud-zipkin?useUnicode=true&characterEncoding=utf8&useSSL=falseusername: rootpassword: 123456zipkin:storage:type: mysql

在程序的啟動類ZipkinServerApplication中注入MySQLStorage的bean,代碼如下:

@SpringBootApplication
@EnableEurekaClient
@EnableZipkinServer
public class ZipkinServerApplication {public static void main(String[] args) {SpringApplication.run(ZipkinServerApplication.class, args);}@Beanpublic MySQLStorage mySQLStorage(DataSource datasource) {return MySQLStorage.builder().datasource(datasource).executor(Runnable::run).build();}
}

只需要這幾步才有http傳輸的鏈路數據就可以存在mysql數據庫中。

源碼下載

最原始的工程:

https://github.com/forezp/SpringCloudLearning/tree/master/chapter-sleuth

采用RabbitMq通訊的工程:

https://github.com/forezp/SpringCloudLearning/tree/master/chapter-sleuth-stream

采用Mysql存儲的工程:

https://github.com/forezp/SpringCloudLearning/tree/master/chapter-sleuth-stream-mysql

采用ES存儲的工程:

https://github.com/forezp/SpringCloudLearning/tree/master/chapter-sleuth-stream-elasticsearch

參考資料

http://cloud.spring.io/spring-cloud-sleuth/spring-cloud-sleuth.html

https://github.com/openzipkin/zipkin

關注我的公眾號

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/387068.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/387068.shtml
英文地址,請注明出處:http://en.pswp.cn/news/387068.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Element表格嵌入復選框以及單選框

1&#xff0c;element 表格嵌入CheckBox 效果圖如下&#xff1a; 2&#xff0c;element結合checkBox實現單選效果如下&#xff1a; html代碼&#xff1a; <template><div><p>shopInfo</p><el-tableref"multipleTable":data"tableDat…

溫故之 “插入排序”

概念&#xff1a;將一個數據插入已經排好序的有序數組中&#xff0c;從而得到一個新的多一個數據的有序數組。 概念理解~~ 將要排序的是一個亂的數組int[] arrays {3, 2, 1, 3, 3}; 在未知道數組元素的情況下&#xff0c;我們只能把數組的第一個元素作為已經排好序的有序數據&…

實驗二3

#include "stdafx.h" #include "stdio.h" int main(int argc, char* argv[]) {int a,b,c; scanf("%d %d %d",&a,&b,&c);if(ab&&bc) printf("等邊三角形");else if((ab&&b!c)||(ac&&c!b)||(bc&a…

webpack來打包你的vue項目,如發現你的vendor.js過大

1.如果你使用了webpack來打包你的vue項目&#xff0c;如發現你的vendor.js過大則可以參考本文的解決方案. 2.造成過大的原因是因為在main.js導入第三庫太多時,webpack合并js時生成了vendor.js(我們習慣把第三方庫放在vendor里面)造成的.如下圖在main.js引用element-ui等第三方…

TF01 簡介

總覽 如何從實體中提取特征&#xff0c;對于很多傳統機器學習算法的性能有巨大影響。 一旦解決了數據表達和特征提取&#xff0c;很多人工智能任務也就解決了90%。 對許多機器學習算法來說&#xff0c;特征提取不是一件簡單的事情。 深度學習解決的核心問題之一就是自動的將簡…

K8s基本概念入門

序言 沒等到風來&#xff0c;綿綿小雨&#xff0c;所以寫個隨筆&#xff0c;聊聊k8s的基本概念。 k8s是一個編排容器的工具&#xff0c;其實也是管理應用的全生命周期的一個工具&#xff0c;從創建應用&#xff0c;應用的部署&#xff0c;應用提供服務&#xff0c;擴容縮容應用…

idea出現找不到實體類

今天經理遇到一個很奇怪的問題&#xff1a; 在使用idea時&#xff0c;就是包真實存在&#xff0c;但是包中的實體類卻無法智能提示&#xff0c;也無法導入成功&#xff1b; 我推薦的解決辦法是重新導入&#xff0c;但是沒有用&#xff0c;經理在網上找了很多解決方式&#xff0…

TF02 入門

計算模型——圖 數據模型——張量 運行模型——會話 TensorFlow計算模型——計算圖 計算圖是TF中最基本的一個概念&#xff0c;TF中的所有計算都會被轉化為計算圖上的結點。 TF是一個通過計算圖的形式來表述計算的編程系統。TF中的每一個計算都是計算圖上的一個節點&#x…

ElasticSearch、Logstash和Kiabana三個開源工具。

一 方案背景 通常&#xff0c;日志被分散的儲存不同的設備上。如果你管理數十上百臺服務器&#xff0c;你還在使用依次登錄每臺機器的傳統方法查閱日志。這樣是不是感覺很繁瑣和效率低下。開源實時日志分析ELK平臺能夠完美的解決日志收集和日志檢索、分析的問題&#xff0c;ELK…

「一本通 6.4 例 4」曹沖養豬(CRT)

復習一下 擴展中國剩余定理 首先考慮兩個同余方程\[ x \equiv a_1\; mod\; m_1\\ x \equiv a_2\; mod\; m_2 \]化成另一個形式\[ x n_1 * m_1 a_1\\ x n_2 * m_2 a_2 \] 聯立可得\[ n_1 * m_1 a_1 n_2 * m_2 a_2\\ n_1 * m_1 - n_2 * m_2 a_2 - a_1 \]有解的前提是\[ \…

06 MapReduce工作機制

MapReduce作業的執行流程 1、提交作業 在提交JobConf對象之後&#xff0c;用戶程序調用JobClient的runJob方法。 runJob方法會先行調用JobSubmissionProtocol接口所定義的submitJob方法&#xff0c;並將作業提交給JobTracker。 緊接著&#xff0c;runJob不斷循環&#xff0…

solr elasticsearch比較

solr&#xff1a; 優點 1、Solr有一個更大、更成熟的用戶、開發和貢獻者社區。 2、支持添加多種格式的索引&#xff0c;如&#xff1a;HTML、PDF、微軟 Office 系列軟件格式以及 JSON、XML、CSV 等純文本格式。 3、Solr比較成熟、穩定。 4、不考慮建索引的同時進行搜索&#xf…

力扣(LeetCode)292. Nim游戲 巴什博奕

你和你的朋友&#xff0c;兩個人一起玩 Nim游戲&#xff1a;桌子上有一堆石頭&#xff0c;每次你們輪流拿掉 1 - 3 塊石頭。 拿掉最后一塊石頭的人就是獲勝者。你作為先手。 你們是聰明人&#xff0c;每一步都是最優解。 編寫一個函數&#xff0c;來判斷你是否可以在給定石頭數…

Spring Cloud應用監控與管理Actuator

由于我們把一個復雜高耦合的單體系統拆分成了多個小型服務&#xff0c;所以部署應用的數量在不斷增長&#xff0c;造成維護復雜度大大提升。所以我們需要一套自動化的監控運維機制&#xff0c;這套運維機制可以不間斷的獲取每個服務應用的各種指標&#xff0c;并根據這些指標信…

2019.04.09 電商25 結算功能1

結算功能要獲取很多數據&#xff0c; 現在的主要問題是要知道獲取對應的商品信息&#xff0c;要知道我選的是哪個的商品信息啊 它們選框的類名都一樣啊&#xff0c;能遍歷嗎&#xff1f;遍歷之后要去獲取&#xff0c;它父級屬性的值 有多少商品就有多少復選框&#xff0c;可以獲…

性能堆分析思路

1、通過top找到對應的耗費資源比較大的進程ID&#xff0c; 2、ps p 進程ID -L -o pcpu,pid,tid,time,tname,cmd 3、然后利用上面面命令來找到對應的線程 4、利用Listthread方法 列出所有線程&#xff0c;與找到對應資源比較大的匹配 5、利用stack查找到對應的堆棧調用代碼&…

第十二屆湖南省賽 (B - 有向無環圖 )(拓撲排序+思維)好題

Bobo 有一個 n 個點&#xff0c;m 條邊的有向無環圖&#xff08;即對于任意點 v&#xff0c;不存在從點 v 開始、點 v 結束的路徑&#xff09;。為了方便&#xff0c;點用 1,2,…,n 編號。 設 count(x,y) 表示點 x 到點 y 不同的路徑數量&#xff08;規定 count(x,x)0&#xff…