springboot第53集:微服務分布式架構,docker-compose,Prometheus,...
簡介:
Prometheus是一款開源監(jiān)控系統(tǒng),起源于SoundCloud的警告工具包。自2012年以來,許多公司和組織開始廣泛采用Prometheus。該項目具有活躍的開發(fā)人員和用戶社區(qū),吸引越來越多的參與者。如今,Prometheus已經(jīng)成為一個獨立的開源項目,擺脫了對任何特定公司的依賴。為了強調(diào)這一點并明確項目的治理結構,Prometheus在2016年加入了Cloud Native Computing Foundation,成為繼Kubernetes之后的又一個成員。
主要特點:
- 采用多維數(shù)據(jù)模型,其中時序由指標名稱和鍵/值標簽構成。
- 支持靈活的查詢語言(PromQL)。
- 無依賴存儲,支持本地和遠程多種模型。
- 使用HTTP協(xié)議,采用拉取模式,簡單易于理解。
- 監(jiān)控目標可通過服務發(fā)現(xiàn)或靜態(tài)配置的方式實現(xiàn)。
- 支持多種統(tǒng)計數(shù)據(jù)模型,圖形化友好。
前言:
- 通常情況下,Prometheus采用二進制安裝,以提高自定義性。
- 隨著云服務時代的發(fā)展,使用Docker部署的用戶不斷增加。
- 兩種安裝方式,以滿足不同場景下的選擇需求。
node-exporter采用go語言開發(fā),專門用來收集Linux系統(tǒng)中硬件、系統(tǒng)指標。既可以用二進制安裝部署,也可以通過容器形式部署
mysql_exporter是用來收集MysQL或者Mariadb數(shù)據(jù)庫相關指標的,mysql_exporter需要連接到數(shù)據(jù)庫并有相關權限。既可以用二進制安裝部署,也可以通過容器形式部署
docker-compose
//指定版本安裝:
$ sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.23.1/\
docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
//對二進制文件賦可執(zhí)行權限
$ sudo chmod +x /usr/local/bin/docker-compose
$ yum -y install docker-compose
$ docker-compose --version
docker-compose version 1.23.1, build 1719ceb
[root@localhost /]# java -version
openjdk version "1.8.0_161"
OpenJDK Runtime Environment (build 1.8.0_161-b14)
OpenJDK 64-Bit Server VM (build 25.161-b14, mixed mode)
[root@localhost /]# rpm -qa | grep java
python-javapackages-3.4.1-11.el7.noarch
java-1.8.0-openjdk-headless-1.8.0.161-2.b14.el7.x86_64
tzdata-java-2018c-1.el7.noarch
java-1.7.0-openjdk-1.7.0.171-2.6.13.2.el7.x86_64
java-1.8.0-openjdk-1.8.0.161-2.b14.el7.x86_64
javapackages-tools-3.4.1-11.el7.noarch
java-1.7.0-openjdk-headless-1.7.0.171-2.6.13.2.el7.x86_64
[root@localhost /]# rpm -e --nodeps java-1.8.0-openjdk-headless-1.8.0.161-2.b14.el7.x86_64
[root@localhost /]# rpm -e --nodeps java-1.8.0-openjdk-1.8.0.161-2.b14.el7.x86_64
[root@localhost /]# rpm -e --nodeps java-1.7.0-openjdk-1.7.0.171-2.6.13.2.el7.x86_64
[root@localhost /]# rpm -e --nodeps java-1.7.0-openjdk-headless-1.7.0.171-2.6.13.2.el7.x86_64
[安裝JDK]
上傳新的jdk-8u191-linux-x64.rpm軟件到/usr/local/src/執(zhí)行以下操作:
[root@localhost src]# rpm -ivh jdk-8u191-linux-x64.rpm
警告:jdk-8u191-linux-x64.rpm: 頭V3 RSA/SHA256 Signature, 密鑰 ID ec551f03: NOKEY
準備中... ################################# [100%]
正在升級/安裝...
1:jdk1.8-2000:1.8.0_191-fcs ################################# [100%]
Unpacking JAR files...
tools.jar...
plugin.jar...
javaws.jar...
deploy.jar...
rt.jar...
jsse.jar...
charsets.jar...
localedata.jar...
[root@localhost src]# java -version
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
[root@localhost src]# java -version
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
[root@localhost src]# vi /etc/profile
JAVA_HOME=/usr/java/jdk1.8.0_191-amd64
JRE_HOME=/usr/java/jdk1.8.0_191-amd64/jre
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
export JAVA_HOME JRE_HOME PATH CLASSPATH
[root@localhost /]# source /etc/profile
[root@localhost /]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/java/jdk1.8.0_191-amd64/bin:/usr/java/jdk1.8.
安裝新版mysql之前,我們需要將系統(tǒng)自帶的mariadb-lib卸載
[root@master ~]# rpm -qa|grep mariadb
mariadb-libs-5.5.41-2.el7_0.x86_64
[root@master ~]# rpm -e mariadb-libs-5.5.41-2.el7_0.x86_64 --nodeps
接下來是初始化數(shù)據(jù)庫,我們使用如下命令均可
[root@master~]# mysqld --initialize
新版的推薦此方法,執(zhí)行生會在/var/log/mysqld.log生成隨機密碼
更改mysql數(shù)據(jù)庫目錄的所屬用戶及其所屬組,然后啟動mysql數(shù)據(jù)庫
[root@master~]# chown mysql:mysql /var/lib/mysql -R
[root@master~]# systemctl start mysqld.service
[root@master~]# cat /var/log/mysqld.log | grep 'password'
[root@master~]# service mysqld restart
[root@master~]# mysql -u root -p
$ sudo yum remove docker
$ sudo yum remove docker \
docker-common \
docker-selinux \
docker-engine
yum --version
3.4.3
Installed: rpm-4.11.3-43.el7.x86_64 at 2020-09-03 03:49
Built : CentOS BuildSystem <http://bugs.centos.org> at 2020-04-01 04:21
Committed: Panu Matilainen <[email protected]> at 2019-10-04
Installed: subscription-manager-1.24.51-1.el7.centos.x86_64 at 2023-05-27 04:39
Built : CentOS BuildSystem <http://bugs.centos.org> at 2022-05-18 15:54
Committed: Christopher Snyder <[email protected]> at 2022-04-18
Installed: yum-3.4.3-167.el7.centos.noarch at 2020-09-03 03:49
Built : CentOS BuildSystem <http://bugs.centos.org> at 2020-04-02 15:56
Committed: CentOS Sources <[email protected]> at 2020-03-31
Installed: yum-plugin-fastestmirror-1.1.31-54.el7_8.noarch at 2020-09-03 03:49
Built : CentOS BuildSystem <http://bugs.centos.org> at 2020-05-12 16:27
Committed: Michal Domonkos <[email protected]> at 2020-03-12
安裝 yum-utils , 這樣就能使用 yum-config-manager 工具設置 Yum 源。
$ sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
執(zhí)行以下命令,添加 Docker 的 Yum 源。
$ sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
$ sudo yum-config-manager --enable docker-ce-edge
$ sudo yum-config-manager --enable docker-ce-test
如想要禁用測試倉庫,可執(zhí)行以下命令:
$ sudo yum-config-manager --disable docker-ce-edge
$ sudo yum makecache fast
$ sudo yum install docker-ce
在生產(chǎn)系統(tǒng)中,可能需要安裝指定版本的 Docker ,而并不總是安裝最新的版本。
執(zhí)行以下命令,即可列出可用的 Docker 版本
$ yum list docker-ce --showduplicates | sort -r
列出 Docker 版本后,可使用以下命令安裝指定版本的 Docker 。
$ sudo yum install
$ sudo yum -y install docker-ce-17.09.0.ce
$ sudo docker run hello-world
docker version
卸載 Docker 軟件包
$ sudo yum remove docker-ce
如需刪除鏡像、容器、卷以及自定義的配置文件,可執(zhí)行以下命令
$ sudo rm -rf /var/lib/docker
InputStream isTrustCa = HttpRequestTest.class.getResourceAsStream("/cert/ca.jks");
InputStream isSelfCert = HttpRequestTest.class.getResourceAsStream("/cert/outgoing.CertwithKey.pkcs12");
KeyStore selfCert = KeyStore.getInstance("pkcs12");
selfCert.load(isSelfCert, "password".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("sunx509");
kmf.init(selfCert, "password".toCharArray());
KeyStore caCert = KeyStore.getInstance("jks");
caCert.load(isTrustCa, "caPassword".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509");
tmf.init(caCert);
SSLContext sc = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = tmf.getTrustManagers();
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
sc.init(kmf.getKeyManagers(), trustManagers, (SecureRandom) null);
// 1. 全局配置證書
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.sslSocketFactory(sc.getSocketFactory(), trustManager)
.hostnameVerifier(TrustAllHostNames.INSTANCE);
HttpRequest.setHttpClient(builder.build());
// 2. 單次請求配置證書
HttpRequest.get("https://123.xxx")
.useConsoleLog(LogLevel.BODY)
.sslSocketFactory(sc.getSocketFactory(), trustManager)
.disableSslValidation()
.execute()
.asString();
mqtt
控制報文中的文本字段編碼為UTF-8格式的字符串。UTF-8 是一個高效的Unicode字符編碼格式,為了支持基于文本的通信,它對ASCII字符的編碼做了優(yōu)化。
每一個字符串都有一個兩字節(jié)的長度字段作為前綴,它給出這個字符串UTF-8編碼的字節(jié)數(shù)
MQTT控制報文
image.png
image.png
image.png
image.png
image.png
homebrew 和 npm 的區(qū)別?
- homebrew,可以理解成 macOS 的軟件管理工具,粗俗點說就是 mac 界的 qq 軟件助手之類的東西。所以通過 brew,安裝什么 chrome瀏覽器啊、atom 編輯器之類的可視化工具也是可以的。
- npm,是 node.js 界的程序/模塊管理工具,也就是說 npm 只管理那些服務于 JavaScript 社區(qū)的程序。而且跨平臺,windows 和 macOS,以及其他類 unix 操作系統(tǒng)都可以用。
- npm是用于 NodeJS 語言的包管理器,NodeJS 是跨平臺的;而 homebrew 是用于OS X系統(tǒng)的包管理器,類似Windows的各種軟件管理工具(所謂XX軟件市場之類)和Linux的apt-get/yum/pacman等。
- npm 是 node.js 的包管理工具,只要有 node 環(huán)境,不管是 windows, macOS, 還是 linux 都可以使用 npm 下載模塊,brew 是 mac 的包管理工具,只有 macOS 上才有。
- Webstorm IntelliJ Darcula Theme (主題插件,提供和 Webstorm一樣的字體和主題)
- 小霸王(通過類似 webview 形式嵌套提供各種小游戲,如魂斗羅、坦克大戰(zhàn)等)
- 韭菜盒子(VSCode 里也可以看股票 & 基金 & 期貨實時數(shù)據(jù),做最好用的投資插件。)
- Live Host (快速編輯 host 文件、每日獲取最佳 github ip 解決 DNS 污染問題。)
- Live Server(快速啟動一個端口服務)
- git blame(可以快速的查看某一行最近的一次修改是誰、什么時候、哪次提交修改的)
- git graph(可以進行版本管理,比如pull、push、修改比較、log、merge)
- gitlens (在vscode中使用git必備插件,功能非常強大)
- filesize(在底部顯示當前文件到大?。?/li>
這行代碼定義了一個靜態(tài)的日志記錄器(Logger)變量,使用 SLF4J(Simple Logging Facade for Java)接口,并通過 LoggerFactory 獲取 Logger 的實例。這是一種常見的在 Java 項目中使用日志的方式。
-
static: 這個變量是靜態(tài)的,屬于類而不是類的實例。靜態(tài)變量在類加載時初始化,并且在整個應用程序的生命周期內(nèi)保持不變。 -
Logger logger: 這是日志記錄器的聲明,類型是Logger。 -
LoggerFactory.getLogger(GPSPosInfo.class): 通過 LoggerFactory 工廠類的getLogger方法,獲取一個Logger實例。傳遞的參數(shù)是類GPSPosInfo.class,這樣在日志中就可以標識出日志消息是從哪個類輸出的。
在使用 SLF4J 進行日志記錄時,常用的日志級別包括 DEBUG、INFO、WARN、ERROR。你可以使用這個 logger 對象記錄不同級別的日志
ObjectUtils.nullSafeEquals 是 Spring Framework 提供的一個用于比較兩個對象是否相等的方法。它考慮了對象為 null 的情況,避免了在比較過程中出現(xiàn)空指針異常。
@NoArgsConstructor 和 @AllArgsConstructor 是 Lombok 提供的注解,用于自動生成類的無參構造方法和全參構造方法。
-
@NoArgsConstructor: 自動生成無參構造方法。使用這個注解的類會在編譯時生成一個默認的無參構造方法,無需手動編寫。 -
@AllArgsConstructor: 自動生成全參構造方法。使用這個注解的類會在編譯時生成一個包含所有成員變量的全參構造方法,無需手動編寫。
@ToString 是 Lombok 提供的注解之一,用于自動生成類的 toString() 方法。它會自動按照類的字段生成一個格式化的字符串,用于方便地輸出對象的內(nèi)容。
創(chuàng)建一個 JedisConnectionFactory 對象,然后通過一系列的設置為該連接工廠配置連接信息,如主機名、端口、密碼、數(shù)據(jù)庫等。接著,配置了連接池相關的參數(shù),包括最大空閑數(shù)、最小空閑數(shù)、最大連接數(shù)、最大等待時間等。
注解 @EqualsAndHashCode,并通過 callSuper = true 參數(shù)指定了在生成 equals 和 hashCode 方法時調(diào)用父類的相應方法。
logger.debug("This is a debug message");
logger.info("This is an info message");
logger.warn("This is a warning message");
logger.error("This is an error message");
- 空值檢查: 在處理數(shù)據(jù)之前進行空值檢查,確保數(shù)據(jù)的完整性。
- 方法拆分: 將長方法拆分成更小的方法,提高代碼的可讀性和可維護性。
- Lambda 表達式: 使用 Lambda 表達式和方法引用來簡化集合處理。
- 常量定義: 將一些常量值提取為靜態(tài)常量,提高代碼的可維護性。
- 異常處理: 添加適當?shù)漠惓L幚頇C制,確保代碼的健壯性。
- 可配置參數(shù): 將一些硬編碼的參數(shù)提取為可配置的參數(shù),使得代碼更具靈活性。
在 Vue 3 中,watch 選項提供了 flush 選項,你可以使用 flush: 'sync' 來確保在組件初始化時立即執(zhí)行一次監(jiān)聽函數(shù)
-
findFirst:
- 獲取第一個匹配的結果。如果沒有找到匹配項,它將返回一個空的
Optional。
orElse(""):
- 如果
Optional為空(表示沒有找到匹配項),則返回一個空字符串 ("")。
!CollectionUtils.isEmpty
是否不為空,以避免空指針異常。
- Lambda 表達式:
- 簡潔性和可讀性: 使用Lambda表達式可以減少冗余的代碼,使代碼更為簡潔,同時提高可讀性。在這種情況下,通過Lambda表達式替代了匿名內(nèi)部類,使得線程的創(chuàng)建過程更為清晰。
- 優(yōu)雅的函數(shù)式編程風格: Lambda表達式是Java對函數(shù)式編程支持的一部分,能夠在一些場景中實現(xiàn)更優(yōu)雅的函數(shù)式編程風格。
- 異步執(zhí)行:
CompletableFuture提供了更為強大和靈活的異步執(zhí)行機制。通過CompletableFuture.runAsync方法,可以在后臺異步執(zhí)行任務,而無需手動創(chuàng)建線程。 - 更好的可組合性:
CompletableFuture支持將多個異步操作組合在一起,形成更為復雜的異步操作流。這使得代碼更易于組織和維護。
CompletableFuture.runAsync(() -> {
})
- 更具體的類型:
- 將方法的返回類型更改為
List<Map<String, Object>>,以便更清晰地表達返回值的類型。
- 修改變量名
page2為更具描述性的page,以提高代碼的可讀性。
- 代碼中沒有對遠程調(diào)用結果和 JSON 解析結果的異常進行處理。在實際代碼中,你可能需要進一步處理這些異常,例如打印日志、拋出自定義異?;蛘吒鶕?jù)業(yè)務需要進行其他處理。
null 的返回:
- 在解析 Feign 調(diào)用結果的過程中,對
null進行了檢查,以避免可能的空指針異常。
- 將最后的返回語句合并,使得代碼更為緊湊。
// 使用 TypeToken 來獲取泛型類型
- 使用
Objects.isNull:
- 使用
Objects.isNull來檢查對象是否為空,這是 Java 7 引入的方法,避免了手動比較== null。
StrUtil.isNotBlank:
- 使用
StrUtil.isNotBlank方法來判斷字符串不為空,這比直接使用!StringUtils.isEmpty更為簡潔。
使用 Optional.ofNullable 以避免 null 值引發(fā)的空指針異常。
使用 map 獲取 對象中的 屬性。為 null,整個鏈式調(diào)用將返回 Optional.empty()。
如果前面的鏈式調(diào)用中存在 null 值,使用 orElse(null) 提供默認值為 null。
使用 ObjectUtils.nullSafeEquals 檢查 locate 是否與已定位枚舉的代碼相等。
-
distinct():
- 使用
distinct進行去重,確保列表中的值是唯一的。
.collect(Collectors.toList()):
- 使用
collect收集結果為列表。
collect(Collectors.toList()) 是 Java 8 中 Stream API 提供的一個方法,它用于將流中的元素收集到一個列表中。
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 省略 getter 和 setter 方法
}
使用 Optional.ofNullable 包裝 ,以避免可能的 null 引用異常。
使用 map 操作將可能為 null 的值轉(zhuǎn)換為字符串表示。如果值為 null,則整個鏈式調(diào)用返回一個空的 Optional。
-
.map(Objects::toString):
- 使用
map操作將可能為null的值轉(zhuǎn)換為字符串表示。如果值為null,則整個鏈式調(diào)用返回一個空的Optional。
.map(Long::parseLong):
- 使用
map操作將字符串表示的時間戳轉(zhuǎn)換為Long類型。如果值為null或無法解析為Long,則整個鏈式調(diào)用返回一個空的Optional。
.orElse(0L):
- 使用
orElse操作提供一個默認值,如果整個鏈式調(diào)用返回空的Optional,則返回默認值0L。
BatteryInfoBO.builder():
-
@Builder注解會在編譯時為帶有該注解的類生成一個建造者模式的構造器。 -
builder()是 Lombok 自動生成的靜態(tài)方法,返回一個構造者對象,你可以使用這個構造者對象設置屬性,并最終調(diào)用build()方法構建對象。
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
An error occurred: This is an example exception.
Exception in thread "main" java.lang.RuntimeException: This is an example exception.
at ExampleClass.main(ExampleClass.java:10)
- 日志體系的抽象:
logger是 SLF4J 或其他日志門面的通用接口,而log可能指代不同的日志框架(例如 Log4j、Java Util Logging 等)。使用logger提供了更高的抽象,使得你可以在不更改代碼的情況下切換底層的日志實現(xiàn)。 - SLF4J 的性能:SLF4J 提供了一種將日志語句延遲計算的機制,只有在達到適當?shù)娜罩炯墑e時才計算日志語句的值。這種延遲計算的機制在性能上有一些優(yōu)勢,因為它可以避免不必要的字符串拼接。
- 日志級別的判斷:SLF4J 支持更多的日志級別(例如 TRACE),而
log通常使用簡單的幾個級別(例如 DEBUG、INFO、WARN、ERROR)。使用logger可以提供更多的日志級別選項。 - 參數(shù)化日志:SLF4J 提供了參數(shù)化日志的機制,可以有效避免手動拼接字符串。這有助于提高代碼的可讀性和維護性。
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
加群聯(lián)系作者vx:xiaoda0423
倉庫地址:https://github.com/webVueBlog/JavaGuideInterview
