apt-key 密鑰管理,apt-secure 原理 驗證鏈 驗證測試_網頁設計公司

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

以設計的實用美學觀點,規劃出舒適、美觀的視覺畫面,有效提昇使用者的心理期待,營造出輕鬆、愉悅的網站瀏覽體驗。

apt-key

用於管理Debian Linux系統中的軟件包密鑰。每個發布的deb包,都是通過密鑰認證的,apt-key用來管理密鑰。

  • apt-key list

    列出已保存在系統中key。包括 /etc/apt/trusted.gpg/etc/apt/trusted.gpg.d/目錄下的密鑰

  • apt-key add <keyname >

    把下載的key添加到本地trusted數據庫中,使用描述性名稱,以gpg或asc作為文件擴展名

  • apt-key del <keyname>

    從本地trusted數據庫刪除key。

  • apt-key update (棄用,直接刪除和添加)

    更新本地trusted數據庫,刪除過期沒用的key。

  • apt-key adv --recv-key

    下載並添加到受信任密鑰環中(不做任何檢查,有風險)

    http://manpages.ubuntu.com/manpages/bionic/en/man8/apt-key.8.html

目錄、文件

/var/cache/apt/archives

已經下載到的.deb軟件包都放在這裏(用 apt-get install 安裝軟件時,軟件包的臨時存放路徑)

/var/lib/apt/lists

存放已安裝和未安裝的軟件列表

使用apt-get update命令會從/etc/apt/sources.list指定的源更新軟件列表,並保存到該目錄

/etc/apt

sources.list 官方軟件源地址(配置為阿里源)

souces.list.d 目錄下是第三方軟件源地址,裏面的文件必須以.list結尾

https://askubuntu.com/a/82844

/etc/apt

trusted.gpg: local trusted keys, new keys will be added here

trusted.gpg.d:additional keyrings can be stored here (by other packages or the administrator)

/usr/bin/

通過 apt 安裝的軟件,命令存放在 /usr/bin/ 目錄下

apt-secure

參考

http://manpages.ubuntu.com/manpages/bionic/en/man8/apt-secure.8.html

SecureApt

基礎元素

Release 文件

Release文件包含分發元數據和索引文件的校驗值

apt 要求隨 Release 文件一起發布一個 Relesase.gpg 的簽名文件,用來驗證安裝包提供者的信息

InRelease 文件

InRelease文件內聯gpg簽名(數據和簽名在一個 InRelease 文件中)

lfp@legion:/var/lib/apt/lists$ ls
...
# 兩個文件
deb.nodesource.com_node%5f12.x_dists_bionic_InRelease
deb.nodesource.com_node%5f12.x_dists_bionic_main_binary-amd64_Packages
...
# 三個文件
dl.google.com_linux_chrome_deb_dists_stable_main_binary-amd64_Packages
dl.google.com_linux_chrome_deb_dists_stable_Release
dl.google.com_linux_chrome_deb_dists_stable_Release.gpg
...

區別:在下載時避免競爭情況

The only difference to Release is that the signature is not detached, but within the file. This is a first step towards getting rid of race conditions when updating Packages/Sources files and mirror updates
running

https://lists.debian.org/debian-devel-announce/2009/11/msg00001.html

校驗值MD5

保護apt安全的基礎

debian archive 包含一個Release文件,隨安裝包一起更新,裡面包含了分發元數據和Package的MD5

Package文件里包含安裝信息以及安裝文件的MD5

驗證鏈

1)驗證簽名文件

簽名文件用來保證Package文件的正確性

  • 如果無法下載 Release 文件或 Release.gpg 簽名無效,則報錯

    W: GPG 錯誤……下列簽名無效 EXPKEYSIG……

    E: 倉庫……沒有数字簽名

    N: 無法安全地用該源進行更新,所以默認禁用該源

    缺少公鑰

  • apt 使用 gpg 來驗證簽名文件

    1. 獲取密鑰

      默認情況下,Debian 系統會預先安裝一些 Debian Archieve 的公鑰,保存在 /etc/apt/trusted.gpg文件中,第三方軟件密鑰需要通過apt-key add [.gpg] 安裝到/etc/apt/sources.list.d/目錄下

      一旦將密鑰添加到apt的密鑰環中,就相當於告訴apt信任該密鑰簽名的一切東西

      如果公鑰丟失,可以通過下面的命令到公鑰服務器上尋找

      apt-key adv --keyserver <server_url> --recv-key <keyId>

      1. 如果更新失敗可能是防火牆端口問題,嘗試指定常規HTTP端口80

      2. 如果連接的是公司的代理服務器,可以嘗試下面的方法

         --keyserver-options http-proxy=<myProxy> --keyserver keyserver.ubuntu.com
        
    2. 通過gpgv簽名驗證工具來驗證簽名的有效性

      詳細介紹參見博文GPG配置、命令、實例與apt-key密鑰測試

      • gpgv 認為apt密鑰環中的密鑰都是可信的,不會檢查其是否過期或被吊銷

      • 通過--keyring [.gpg file]指定密鑰環,-v可以显示更多信息

        apt 密鑰環保存在 /etc/apt/trusted.gpg 或 /etc/apt/trusted.gpg.d/xxx.gpg 中

      • 單獨簽名驗證

        gpgv --keyring /etc/apt/trusted.gpg [Release.gpg file] [Release file]

      • 內聯簽名驗證

        ※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

        網站的第一印象網頁設計,決定了客戶是否繼續瀏覽的意願。台北網動廣告製作的RWD網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上它。

        gpgv --keyring /etc/apt/trusted.gpg [InRelease file]

2)驗證Package文件

Package 文件中包含軟件不同版本的信息,用來保證deb文件的正確性

  1. 從Release文件或InRelease文件中提取Package文件的MD5

    sed -n "s,main/binary-amd64/Packages$,,p" [Release / InRelease file]

  2. 計算Package文件的MD5

    md5sum [Packages file]

3)驗證安裝包

  1. 從Package文件中提取deb文件的MD5

    sed -n "s/MD5sum: //p" [Packages file]

  2. 從apt緩存中提取軟件的MD5

    apt-cache show [package_name] | sed -n "s/MD5sum: //p"

  3. 計算本地已下載deb文件的MD5

    md5sum [.deb file]

驗證測試

chrome 驗證

特點

  1. chrome 是Release文件和簽名文件[.gpg]分離的
  2. 使用本地密鑰環驗證(保存在 /etc/apt/trusted.gpg)

官方聲明

https://www.google.com/linuxrepositories/

Release.gpg文件

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAABCAAGBQJeqbVjAAoJEHi9ZUc8s70TgUIP/RzWWeDxvtGrmLoWt0csiD+O
wrAr86yDSSzFasjKPcS+SQzs5FnCamFdTT7KD2C6thwRgCLR3oumHMuKC5hnb9/4
GP7qMCDYQEMR2IQcWfKPoT2fAX1eKDKJtv5qsAEdSb3uIW27zkdvUA4j4N6w4toA
RA24VV/VSK1p3T4j3HQzN6fOta0wA3onN9bPrcXZAig7Tm78SKbjYEzd1jxIeQQE
aTKP6AfHPnn8UFNkVyifigsd1Usaex3BJumzHq+jLhTtJDcLjqQNQdcKs48xY0Ek
lZJHY1w/p8e06Y16fXxO/Mh6+Kmu+ZBOKEo3VjshBOISASkMXG/JPEjWadP62A8S
lprRALXaWLcF5P5RYjdqhatCxH37SQr3iqqQmdC/PSCDq/Z5cYiVIElyUeHnMZ6i
X6wYvOd1n9p64VgUAINpbY0NeWZc0Kj1pMXaL+bohUnH8YWDfIhFdQDdQbd0DxBY
xgSTAuUn4DkMKZvtqVEsAIZk5VrYjWykdvdaZad8DdAhVxuHzl1xVEXRDyDhxvUN
IE2oOMv1N5MrXKHtGJLITlv0SAtbZRSaez91dudr9eoln8bZ+oFI9VrHO0xKO2/W
/VRMExkQC51OHCEtZKfsqqSAEG0sctvagq5MElCElZkmD/P72MuznRBgjbfeKs/B
JMSaAmp1mus5Mo7BZND6
=/bSj
-----END PGP SIGNATURE-----                      
驗證簽名
lfp@legion:/var/lib/apt/lists$ gpgv --keyring /etc/apt/trusted.gpg dl.google.com_linux_chrome_deb_dists_stable_Release.gpg dl.google.com_linux_chrome_deb_dists_stable_Release
gpgv: 簽名建立於 2020年04月30日 星期四 01時12分03秒 CST
gpgv:                使用 RSA 密鑰 78BD65473CB3BD13
gpgv: 完好的簽名,來自於“Google Inc. (Linux Packages Signing Authority) <linux-packages-keymaster@google.com>”

Release文件

包含Package文件的MD5

Origin: Google LLC
Label: Google
Suite: stable
Codename: stable
Version: 1.0
Date: Wed, 29 Apr 2020 17:11:57 UTC
Architectures: amd64
Components: main
Description: Google chrome-linux software repository
MD5Sum:
 2e55673e5a00d8837090d0922e198520 4599 main/binary-amd64/Packages
 eafbe9cc415e53d2280c86a0d64be27d 1133 main/binary-amd64/Packages.gz
 156e5ea7a0c6bed5973a68a45e546dc9 151 main/binary-amd64/Release
SHA1:
 9525687fab2b772c511c9e9ae5c7c7b6d8b92e2a 4599 main/binary-amd64/Packages
 c364469ff8578e7c7323b030ad3e459b9192a4ea 1133 main/binary-amd64/Packages.gz
 0f4348c2d4d7cc1f8e59b5934d87f1ca872f6e34 151 main/binary-amd64/Release
SHA256:
 667d27f55652d51c57c0eaab074dd2d365e373ebd5b6e1277b18606cc5177c1b 4599 main/binary-amd64/Packages
 7dc589a54517f36e7786b101555e9f1d2c6e2058b1b3743c575eb8c165094620 1133 main/binary-amd64/Packages.gz
 c1e3c9318381862306adcdc4fd4fe2d85be8aa4c4f3dcbb40fce80413f588286 151 main/binary-amd64/Release

提取Package文件的MD5
lfp@legion:/var/lib/apt/lists$ sed -n "s,main/binary-amd64/Packages$,,p" dl.google.com_linux_chrome_deb_dists_stable_Release
 2e55673e5a00d8837090d0922e198520 4599 
 9525687fab2b772c511c9e9ae5c7c7b6d8b92e2a 4599 
 667d27f55652d51c57c0eaab074dd2d365e373ebd5b6e1277b18606cc5177c1b 4599 

計算Package文件的MD5
lfp@legion:/var/lib/apt/lists$ md5sum dl.google.com_linux_chrome_deb_dists_stable_main_binary-amd64_Packages 
2e55673e5a00d8837090d0922e198520  dl.google.com_linux_chrome_deb_dists_stable_main_binary-amd64_Packages

Package文件可信

2e55673e5a00d8837090d0922e198520 一致

Package文件

包含deb文件的MD5

# 包含各種版本的chrome
Package: google-chrome-beta
...
Package: google-chrome-stable
Version: 81.0.4044.129-1
Architecture: amd64
Maintainer: Chrome Linux Team <chromium-dev@chromium.org>
Installed-Size: 229948
Pre-Depends: dpkg (>= 1.14.0)
Depends: ca-certificates, fonts-liberation, libappindicator3-1, libasound2 (>= 1.0.16), libatk-bridge2.0-0 (>= 2.5.3), libatk1.0-0 (>= 2.2.0), libatspi2.0-0 (>= 2.9.90), libc6 (>= 2.16), libcairo2 (>= 1.6.0), libcups2 (>= 1.4.0), libdbus-1-3 (>= 1.5.12), libdrm2 (>= 2.4.38), libexpat1 (>= 2.0.1), libgbm1 (>= 8.1~0), libgcc1 (>= 1:3.0), libgdk-pixbuf2.0-0 (>= 2.22.0), libglib2.0-0 (>= 2.39.4), libgtk-3-0 (>= 3.9.10), libnspr4 (>= 2:4.9-2~), libnss3 (>= 2:3.22), libpango-1.0-0 (>= 1.14.0), libpangocairo-1.0-0 (>= 1.14.0), libx11-6 (>= 2:1.4.99.1), libx11-xcb1, libxcb-dri3-0, libxcb1 (>= 1.6), libxcomposite1 (>= 1:0.3-1), libxcursor1 (>> 1.1.2), libxdamage1 (>= 1:1.1), libxext6, libxfixes3 (>= 1:5.0), libxi6 (>= 2:1.2.99.4), libxrandr2 (>= 2:1.2.99.3), libxrender1, libxss1, libxtst6, wget, xdg-utils (>= 1.0.2)
Recommends: libu2f-udev, libvulkan1
Provides: www-browser
Priority: optional
Section: web
Filename: pool/main/g/google-chrome-stable/google-chrome-stable_81.0.4044.129-1_amd64.deb
Size: 67137920
SHA256: fe140112304b243240a5f6b287105fd5b7d6e48c6ff682194a62c8d08fd0ed5b
SHA1: f5f984d1a1419b803a7a26dbda1d04fb8313c4b3
# md5
MD5sum: 3705bb8b32a9b4cfcc4440c14966acbc
Description: The web browser from Google
 Google Chrome is a browser that combines a minimal design with sophisticated technology to make the web faster, safer, and easier.

Package: google-chrome-unstable
...
提取deb文件的MD5
lfp@legion:/var/lib/apt/lists$ sed -n "s/MD5sum: //p" dl.google.com_linux_chrome_deb_dists_stable_main_binary-amd64_Packages 
9c6634a7bbda0cedb2d218410c0a06c2
3705bb8b32a9b4cfcc4440c14966acbc
fe9bc72b7cb12549a69187c0e393f930
從apt緩存中提取chrome信息
lfp@legion:/var/lib/apt/lists$ apt-cache show chromium-browser | sed -n "s/MD5sum: //p"
# 沒有匹配的md5,打開瀏覽器,查看chrome的版本信息是:版本 81.0.4044.129(正式版本) (64 位)
# apt-cache show chromium-browser 显示信息如下,沒有找到同一個版本,於是從Google下載了一個最新的安裝包
# Package: chromium-browser
# Filename: pool/universe/c/chromium-browser/chromium-browser_80.0.3987.163-0ubuntu0.18.04.1_amd64.deb
6dcd58431410a691c847a709765f7248
dfd394ff98654f1e0a97d204f7343ab1
計算deb文件的MD5

從Google那裡下載了一個deb安裝包

lfp@legion:~/Downloads$ md5sum google-chrome-stable_current_amd64.deb 
3705bb8b32a9b4cfcc4440c14966acbc  google-chrome-stable_current_amd64.deb
deb文件可信

3705bb8b32a9b4cfcc4440c14966acbc 一致

nodejs驗證

特點

  1. nodejs 是InRelease文件,內聯簽名
  2. 使用本地密鑰環驗證(保存在 /etc/apt/trusted.gpg)

InRelease文件

包含Package文件的MD5

驗證簽名
lfp@legion:/var/lib/apt/lists$ gpgv --keyring /etc/apt/trusted.gpg deb.nodesource.com_node%5f12.x_dists_bionic_InRelease 
gpgv: 簽名建立於 2020年04月30日 星期四 00時53分13秒 CST
gpgv:                使用 RSA 密鑰 9FD3B784BC1C6FC31A8A0A1C1655A0AB68576280
gpgv: 完好的簽名,來自於“NodeSource <gpg@nodesource.com>”

lfp@legion:/var/lib/apt/lists$ vim deb.nodesource.com_node%5f12.x_dists_bionic_InRelease

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Origin: Node Source
Label: Node Source
Codename: bionic
Date: Wed, 29 Apr 2020 16:53:13 UTC
Architectures: i386 amd64 armhf arm64
Components: main
Description: Apt Repository for the Node.JS 12.x Branch
MD5Sum:
 d41d8cd98f00b204e9800998ecf8427e 0 main/binary-i386/Packages
 7029066c27ac6f5ef18d660d5741979a 20 main/binary-i386/Packages.gz
 cf52b42ebdc37bfabc86a5db93fcbdbc 130 main/binary-i386/Release
 # amd64
 6d2cd675d3c647d51a8ee0349754a976 1195 main/binary-amd64/Packages
 608cc59026b960ec64b97bcbeaa68003 765 main/binary-amd64/Packages.gz
 049fa528953b36ae91d8fe360618d46f 131 main/binary-amd64/Release
 14ce3c619a83d518ee3e433dedbdf26a 1216 main/binary-armhf/Packages
 219c6a1d7d300d409d4bb8249911d58f 775 main/binary-armhf/Packages.gz
 8064ccb91382a3c1cbade0c462ee18b3 131 main/binary-armhf/Release
 45ad97bad6053d65a462c352219fa962 1195 main/binary-arm64/Packages
 8afb33e583bf54aabaeb9b3378c3ca26 766 main/binary-arm64/Packages.gz
 670d019ad65bf455298c252afc334bff 131 main/binary-arm64/Release
 d41d8cd98f00b204e9800998ecf8427e 0 main/source/Sources
 7029066c27ac6f5ef18d660d5741979a 20 main/source/Sources.gz
 e4627d3fe224f8b3c07d9a69c88bedd2 132 main/source/Release

提取Package文件的MD5
sed -n "s,main/binary-amd64/Packages$,,p" deb.nodesource.com_node%5f12.x_dists_bionic_InRelease 
 6d2cd675d3c647d51a8ee0349754a976 1195 
 4615cf89691b8c95c052a84b09a1d24079268403 1195 
 8ec2d3674dc82a29ca759a2cf59cfe67a2b6c3a42106c523b11f93791a1e538e 1195 
計算Package文件的MD5
lfp@legion:/var/lib/apt/lists$ md5sum deb.nodesource.com_node%5f12.x_dists_bionic_main_binary-amd64_Packages 
6d2cd675d3c647d51a8ee0349754a976  deb.nodesource.com_node%5f12.x_dists_bionic_main_binary-amd64_Packages
Package文件可信

6d2cd675d3c647d51a8ee0349754a976 一致

Package文件

包含deb文件的MD5

Package: nodejs
Version: 12.16.3-1nodesource1
Architecture: amd64
Maintainer: Chris Lea <chl@nodesource.com>
Installed-Size: 87857
Depends: libc6 (>= 2.17), libgcc1 (>= 1:3.4), libstdc++6 (>= 4.8), python-minimal, ca-certificates
Conflicts: nodejs-dev, nodejs-legacy, npm
Replaces: nodejs-dev (<= 0.8.22), nodejs-legacy, npm (<= 1.2.14)
Provides: nodejs-dev, nodejs-legacy, npm
Homepage: https://nodejs.org
Priority: optional
Section: web
Filename: pool/main/n/nodejs/nodejs_12.16.3-1nodesource1_amd64.deb
Size: 17989662
SHA256: b2d1a6327f5a34c097d7fb5eeed8357d9758c09b30e356f45dfa01cc24103108
SHA1: de90a1776ee9995b3121ab68f49fef3cb110ce65
MD5sum: 9f87646d2782a572da1f965cf96f974f
Description: Node.js event-based server-side javascript engine
 Node.js is similar in design to and influenced by systems like
 Ruby's Event Machine or Python's Twisted.
 .
 It takes the event model a bit further - it presents the event
 loop as a language construct instead of as a library.
 .
 Node.js is bundled with several useful libraries to handle server tasks :
 System, Events, Standard I/O, Modules, Timers, Child Processes, POSIX,
 HTTP, Multipart Parsing, TCP, DNS, Assert, Path, URL, Query Strings.

提取deb文件的MD5
lfp@legion:/var/lib/apt/lists$ sed -n "s/MD5sum: //p" deb.nodesource.com_node%5f12.x_dists_bionic_main_binary-amd64_Packages 
9f87646d2782a572da1f965cf96f974f
從apt緩存中提取nodejs信息
lfp@legion:/var/lib/apt/lists$ apt-cache show nodejs | sed -n "s/MD5sum: //p"
# 包含不同版本的信息
9f87646d2782a572da1f965cf96f974f
0e6643fbe872255dbfaebd5449813d8f
02d7a42a30a7d72b78d9bc4a7ceb5a5a
3930b41c309e69cc0bd3737cfc1e7d31
計算deb文件的md5
lfp@legion:/var/lib/apt/lists$ md5sum /var/cache/apt/archives/nodejs_12.16.3-1nodesource1_amd64.deb 
9f87646d2782a572da1f965cf96f974f  /var/cache/apt/archives/nodejs_12.16.3-1nodesource1_amd64.deb
deb文件可信

9f87646d2782a572da1f965cf96f974f 一致

smplayer 驗證

特點

  1. smplayer 是InRelease文件,內聯簽名
  2. 使用第三方密鑰環去驗證(保存在/etc/apt/trusted.gpg.d目錄中)

驗證流程

  1. 簽名

    lfp@legion:/var/lib/apt/lists$ gpgv --keyring /etc/apt/trusted.gpg.d/rvm_ubuntu_smplayer.gpg ppa.launchpad.net_rvm_smplayer_ubuntu_dists_bionic_InRelease 
    gpgv: 簽名建立於 2020年04月13日 星期一 23時45分47秒 CST
    gpgv:                使用 RSA 密鑰 A7E13D78E4A4F4F4
    gpgv: 完好的簽名,來自於“Launchpad PPA named smplayer for rvm”
    
  2. Package

    MD5 7aa109a3525c661e783e9b943e4b46fa

    lfp@legion:/var/lib/apt/lists$ sed -n "s,main/binary-amd64/Packages$,,p" ppa.launchpad.net_rvm_smplayer_ubuntu_dists_bionic_InRelease 
     7aa109a3525c661e783e9b943e4b46fa             2909 
     29ca94a4f3a57c328b31789bce66cd6bbaa819e2             2909 
     6586e6ef8389cddb47ae0f7f7761ddbfedab35ed3ffbb3b10b4a1f91264577ae             2909 
    
    lfp@legion:/var/lib/apt/lists$ md5sum ppa.launchpad.net_rvm_smplayer_ubuntu_dists_bionic_main_binary-amd64_Packages 
    7aa109a3525c661e783e9b943e4b46fa  ppa.launchpad.net_rvm_smplayer_ubuntu_dists_bionic_main_binary-amd64_Packages
    
  3. deb

    MD5 601afc2fe220b608acb1e5b920afca96

    lfp@legion:/var/lib/apt/lists$ sed -n "s/MD5sum: //p" ppa.launchpad.net_rvm_smplayer_ubuntu_dists_bionic_main_binary-amd64_Packages 
    601afc2fe220b608acb1e5b920afca96
    b569cc540016f0b04fae5dd15a1434eb
    4eb1111c66b5087e7489cf7526321a9e
    45a466ca713b566f920d9e6414212552
    
    lfp@legion:/etc/apt/trusted.gpg.d$ apt-cache show smplayer | grep -E 'MD5|Filename'
    Filename: pool/main/s/smplayer/smplayer_20.4.2-1~bionic1_amd64.deb
    MD5sum: 601afc2fe220b608acb1e5b920afca96
    Filename: pool/universe/s/smplayer/smplayer_18.2.2~ds0-1_amd64.deb
    MD5sum: 7fdfc2f64d835cf5f7a38035523379a2
    
    lfp@legion:/var/cache/apt/archives$ md5sum smplayer_20.4.2-1~bionic1_amd64.deb 
    601afc2fe220b608acb1e5b920afca96  smplayer_20.4.2-1~bionic1_amd64.deb
    

沒有公鑰或簽名無效測試

  1. 本地沒有該公鑰

  2. 本地公鑰過期

    猜測:此時軟件發布者應該會創建一個新的子密鑰來簽名,而本地公鑰是過期的,情況類似於用一個錯誤的密鑰驗證簽名文件

    # 使用錯誤的密鑰去驗證簽名文件
    lfp@legion:~$ gpgv --keyring /etc/apt/trusted.gpg.d/sogou-archive-keyring.gpg /var/lib/apt/lists/typora.io_linux_._InRelease 
    gpgv: 簽名建立於 2020年03月04日 星期三 00時11分02秒 CST
    gpgv:                使用 RSA 密鑰 4AC441BE68B4ADAB7439FBF9BA300B7755AFCFAE
    gpgv:                issuer "abner@typora.io"
    gpgv: 無法檢查簽名:沒有公鑰
    

相關問題

EXPKEYSIG 沒有数字簽名

問題:執行apt update 出現如下錯誤

W: GPG 錯誤:https://dl.yarnpkg.com/debian stable InRelease: 下列簽名無效: EXPKEYSIG 23E7166788B63E1E Yarn Packaging yarn@dan.cx
E: 倉庫 “https://dl.yarnpkg.com/debian stable InRelease” 沒有数字簽名。
N: 無法安全地用該源進行更新,所以默認禁用該源

原因:

安裝第三方軟件的時候會同時安裝軟件倉庫地址以及密鑰,上述問題是因為本地的密鑰過期了,需要更新

https://github.com/yarnpkg/yarn/issues/7866#issue-558663837

辦法:更新密鑰

  1. 找到該軟件安裝方法中添加密鑰的方式(如yarn的安裝步驟一),再次執行即可

  2. 直接搜索密鑰添加到密鑰列表

    apt-key adv --keyserver <server_url> --recv-key <keyId>
    
  3. 到服務器找密鑰手動安裝

    1. 獲取 pub_key的ID

      23E7166788B63E1E

    2. 到密鑰服務器上以十六進制形式搜索

      http://keyserver.ubuntu.com/

      0x23E7166788B63E1E

    3. 單擊 pub鏈接,複製密鑰內容並保存到本地,以txt格式

      key.txt

      密鑰內容

    4. 終端添加密鑰

      sudo apt-key add key.txt

      ok

    5. 更新

      sudo apt update

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

台中景泰電動車行只是一個單純的理由,將來台灣的環境,出門可以自由放心的深呼吸,讓空氣回歸自然的乾淨,減少污染,留給我們下一代有好品質無空污的優質環境

真正越野賽車和實際買到的SUV有什麼區別?_網頁設計公司

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網站的第一印象網頁設計,決定了客戶是否繼續瀏覽的意願。台北網動廣告製作的RWD網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上它。

2、進氣系統一輛標準的帕傑羅過水雖然沒有問題,但是速度要十分慢,快過沙子慢淌水這個道理大家都懂,但是賽車時前方的水坑也要全速沖,所以不改進氣車子過水的時候可能發動機就進水了。3、懸架懸架系統主要承擔緩衝和吸收衝擊的作用,以保護車身機械系統以及車輛電氣系統,如果懸架的強度不夠不能支持車輛飛躍等,這樣就導致每次爬坡到坡頂都必須減速,會浪費掉許多的時間。

對於越野車,不同的人有不同的理解,但是對於大多數人來說,大梁四驅就是越野車,可是如果越野賽車呢?

越野賽車大家都十分陌生,對於小編來說也一樣,不過通過這次參加騰衝站COC越野賽的機會,小編有幸感受到了真正的越野賽車的魅力。

越野賽車和越野車的區別在哪呢?

速度

歸根結底就在於速度兩字,其實對於豐田普拉多/三菱帕傑羅這類的我們熟悉的越野車來說,越野場地的大多數項目都不是問題,但是如果讓一輛原廠狀態的大切諾基來用越野賽車的跑法跑越野賽道的話,可能跑不完一圈車子就趴窩了。

原因就在於越野賽車需要有較高的速度,這樣就需要車子的輪胎/車身/懸架能夠承受更大的衝擊,因此真正的越野賽車對於這些方面都會進行改裝,那麼如果想讓你的車擁有迅速快速地跑完越野賽道的實力,需要改裝哪些地方呢?

1、輪胎

輪胎是和路面接觸的地方,越野賽場的路面可不一般,看似平坦實際上尖石粒到處都是,而越野賽車需要以70km/h左右的高速度碾壓路面,因此輪胎的耐用性十分重要,

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

台中景泰電動車行只是一個單純的理由,將來台灣的環境,出門可以自由放心的深呼吸,讓空氣回歸自然的乾淨,減少污染,留給我們下一代有好品質無空污的優質環境

而且在泥地、沙地也需要輪胎提供足夠的抓地力,在車輛飛躍的時候輪胎也需要承擔並緩衝巨大的衝擊力。所以再強的越野車,如果輪胎不行,那麼也是白搭。

2、進氣系統

一輛標準的帕傑羅過水雖然沒有問題,但是速度要十分慢,快過沙子慢淌水這個道理大家都懂,但是賽車時前方的水坑也要全速沖,所以不改進氣車子過水的時候可能發動機就進水了。

3、懸架

懸架系統主要承擔緩衝和吸收衝擊的作用,以保護車身機械系統以及車輛電氣系統,如果懸架的強度不夠不能支持車輛飛躍等,這樣就導致每次爬坡到坡頂都必須減速,會浪費掉許多的時間。

4、前後包圍

為什麼包圍要改呢?一般車輛的接近角和離去角都比較小,對於高強度越野來說肯定是不夠的,所以拆掉前後包圍是最簡單的做法,也是普遍採取的做法。

5、防翻滾架/座位

這個雖然和性能無關,但是卻是保護安全的神器,防翻滾架是每部賽車的標配,即使車輛翻滾散架,防翻滾架都會保持完整。也能夠保護車內的駕乘人員。而安全帶則無需多言了,你以為3點式安全帶夠用?

最後的最後,可能有人就會問了,我不會把車改成這個樣子啊,其實小編想說的是,有的人開車遇到溝坎減速帶什麼的都不減速的,原理其實和賽車一樣,如果你真的需要暴力開,還真的要把車子改成高強度的狀態,量產車隨便虐只會大大減少壽命,甚至會直接弄毀車輛。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

以設計的實用美學觀點,規劃出舒適、美觀的視覺畫面,有效提昇使用者的心理期待,營造出輕鬆、愉悅的網站瀏覽體驗。

超乾貨!為了讓你徹底弄懂MySQL事務日誌,我通宵肝出了這份圖解!_如何寫文案

※別再煩惱如何寫文案,掌握八大原則!

什麼是銷售文案服務?A就是幫你撰寫適合的廣告文案。當您需要販售商品、宣傳活動、建立個人品牌,撰寫廣告文案都是必須的工作。

還記得剛上研究生的時候,導師常掛在嘴邊的一句話,“科研的基礎不過就是數據而已。”如今看來,無論是人文社科,還是自然科學,或許都可在一定程度上看作是數據的科學。

倘若剝開研究領域的外衣,將人的操作抽象出來,那麼科研的過程大概就是根據數據流動探索其中的未知信息吧。當然科學研究的範疇涵蓋甚廣,也不是一兩句話能夠拎得清的。不過從這個角度上的闡述,也只是為了引出數據的重要性。

在當今社會,充斥着大量的數據。從眾多APP上的賬戶資料到銀行信用體系等個人檔案,都離不開對大量數據的組織、存儲和管理。而這,便是數據庫存在的目的和價值。

目前數據庫的類型主要分為兩種,一種是關係型數據庫,另一種是非關係型數據庫(NoSQL)。而我們今天的主角MySQL就是關係型數據庫中的一種。

1 關係型數據庫與NoSQL

關係型數據庫,顧名思義,是指存儲的數據之間具有關係。這種所謂的關係通常用二維表格中的行列來表示,即一個二維表的邏輯結構能夠反映表中數據的存儲關係。

概念總是拗口難懂的。那麼簡單來說,關係型數據庫的存儲就是按照表格進行的。數據的存儲實際上就是對一個或者多個表格的存儲。通過對這些表格進行分類、合併、連接或者選取等運算來實現對數據庫的管理。常見的關係型數據庫有MySQL、Oracle、DB2和SqlServer等。

非關係型數據庫(NoSQL)是相對於關係型數據庫的一種泛指,它的特點是去掉了關係型數據庫中的關係特性,從而可獲得更好的擴展性。NoSQL並沒有嚴格的存儲方式,但採用不同的存儲結構都是為了獲得更高的性能和更高的併發。NoSQL根據存儲方式可分為四大類,鍵值存儲數據庫、列存儲數據庫、文檔型數據庫和圖形數據庫。這四種數據的存儲原理不盡相同,因而在應用場景上也有些許的差異。一般常用的有作為數據緩存的redis和分佈式系統的HBase。目前常見的數據庫排名可見網站:

https://db-engines.com/en/ranking

關係型數據庫與非關係型數據庫本質上的區別就在於存儲的數據是否具有一定的邏輯關係,由此產生的兩類數據庫看的性能和優劣勢上也有一定的區別。二者對比可見下圖。

2 MySQL簡介

介紹

在關係型數據庫中,MySQL可以說是其中的王者。它是目前最流行的數據庫之一,由瑞典 MySQL AB 公司開發,目前屬於 Oracle 公司。MySQL數據庫具有以下幾個方面的優勢:

  • 體積小、速度快;
  • 代碼開源,採用了 GPL 協議,可以修改源碼來開發自己的 MySQL 系統;
  • 支持大型的數據庫,可以處理擁有上千萬條記錄的大型數據庫;
  • 使用標準的 SQL 數據語言形式,並採用優化的 SQL 查詢算法,有效地提高查詢速度;
  • 使用 C 和 C++ 編寫,並使用多種編譯器進行測試,保證源代碼的可移植性;
  • 可運行在多個系統上,並且支持多種語言;
  • 核心程序採用完全的多線程編程,可以靈活地為用戶提供服務,充分利用CPU資源。

邏輯架構

MySQL的邏輯架構可分為四層,包括連接層、服務層、引擎層和存儲層,各層的接口交互及作用如下圖所示。需要注意的是,由於本文將主要講解事務的實現原理,因此下文針對的都是InnoDB引擎下的情況。

連接層:負責處理客戶端的連接以及權限的認證。

服務層:定義有許多不同的模塊,包括權限判斷,SQL接口,SQL解析,SQL分析優化, 緩存查詢的處理以及部分內置函數執行等。MySQL的查詢語句在服務層內進行解析、優化、緩存以及內置函數的實現和存儲。

引擎層:負責MySQL中數據的存儲和提取。MySQL中的服務器層不管理事務,事務是由存儲引擎實現的。其中使用最為廣泛的存儲引擎為InnoDB,其它的引擎都不支持事務。

存儲層:負責將數據存儲與設備的文件系統中。

3 MySQL事務

事務是MySQL區別於NoSQL的重要特徵,是保證關係型數據庫數據一致性的關鍵技術。事務可看作是對數據庫操作的基本執行單元,可能包含一個或者多個SQL語句。這些語句在執行時,要麼都執行,要麼都不執行。

事務的執行主要包括兩個操作,提交和回滾。

提交:commit,將事務執行結果寫入數據庫。

回滾:rollback,回滾所有已經執行的語句,返回修改之前的數據。

MySQL事務包含四個特性,號稱ACID四大天王。

原子性(Atomicity) :語句要麼全執行,要麼全不執行,是事務最核心的特性,事務本身就是以原子性來定義的;實現主要基於undo log日誌實現的。

持久性(Durability :保證事務提交后不會因為宕機等原因導致數據丟失;實現主要基於redo log日誌。

隔離性(Isolation) :保證事務執行盡可能不受其他事務影響;InnoDB默認的隔離級別是RR,RR的實現主要基於鎖機制、數據的隱藏列、undo log和類next-key lock機制。

一致性(Consistency) :事務追求的最終目標,一致性的實現既需要數據庫層面的保障,也需要應用層面的保障。

原子性

事務的原子性就如原子操作一般,表示事務不可再分,其中的操作要麼都做,要麼都不做;如果事務中一個SQL語句執行失敗,則已執行的語句也必須回滾,數據庫退回到事務前的狀態。只有0和1,沒有其它值。

事務的原子性表明事務就是一個整體,當事務無法成功執行的時候,需要將事務中已經執行過的語句全部回滾,使得數據庫回歸到最初未開始事務的狀態。

事務的原子性就是通過undo log日誌進行實現的。當事務需要進行回滾時,InnoDB引擎就會調用undo log日誌進行SQL語句的撤銷,實現數據的回滾。

持久性

事務的持久性是指當事務提交之後,數據庫的改變就應該是永久性的,而不是暫時的。這也就是說,當事務提交之後,任何其它操作甚至是系統的宕機故障都不會對原來事務的執行結果產生影響。

事務的持久性是通過InnoDB存儲引擎中的redo log日誌來實現的,具體實現思路見下文。

隔離性

原子性和持久性是單個事務本身層面的性質,而隔離性是指事務之間應該保持的關係。隔離性要求不同事務之間的影響是互不干擾的,一個事務的操作與其它事務是相互隔離的。

由於事務可能並不只包含一條SQL語句,所以在事務的執行期間很有可能會有其它事務開始執行。因此多事務的併發性就要求事務之間的操作是相互隔離的。這一點跟多線程之間數據同步的概念有些類似。

鎖機制

事務之間的隔離,是通過鎖機制實現的。當一個事務需要對數據庫中的某行數據進行修改時,需要先給數據加鎖;加了鎖的數據,其它事務是不運行操作的,只能等待當前事務提交或回滾將鎖釋放。

鎖機制並不是一個陌生的概念,在許多場景中都會利用到不同實現的鎖對數據進行保護和同步。而在MySQL中,根據不同的劃分標準,還可將鎖分為不同的種類。

按照粒度劃分:行鎖、表鎖、頁鎖

按照使用方式劃分:共享鎖、排它鎖

按照思想劃分:悲觀鎖、樂觀鎖

鎖機制的知識點很多,由於篇幅不好全部展開講。這裏對按照粒度劃分的鎖進行簡單介紹。

粒度:指數據倉庫的數據單位中保存數據的細化或綜合程度的級別。細化程度越高,粒度級就越小;相反,細化程度越低,粒度級就越大。

MySQL按照鎖的粒度劃分可以分為行鎖、表鎖和頁鎖。

行鎖:粒度最小的鎖,表示只針對當前操作的行進行加鎖;

表鎖:粒度最大的鎖,表示當前的操作對整張表加鎖;

頁鎖:粒度介於行級鎖和表級鎖中間的一種鎖,表示對頁進行加鎖。

這三種鎖是在不同層次上對數據進行鎖定,由於粒度的不同,其帶來的好處和劣勢也不一而同。

表鎖在操作數據時會鎖定整張表,因而併發性能較差;

行鎖則只鎖定需要操作的數據,併發性能好。但是由於加鎖本身需要消耗資源(獲得鎖、檢查鎖、釋放鎖等都需要消耗資源),因此在鎖定數據較多情況下使用表鎖可以節省大量資源。

MySQL中不同的存儲引擎能夠支持的鎖也是不一樣的。MyIsam只支持表鎖,而InnoDB同時支持表鎖和行鎖,且出於性能考慮,絕大多數情況下使用的都是行鎖。

併發讀寫問題

在併發情況下,MySQL的同時讀寫可能會導致三類問題,臟讀、不可重複度和幻讀。

(1)臟讀:當前事務中讀到其他事務未提交的數據,也就是臟數據。

以上圖為例,事務A在讀取文章的閱讀量時,讀取到了事務B為提交的數據。如果事務B最後沒有順利提交,導致事務回滾,那麼實際上閱讀量並沒有修改成功,而事務A卻是讀到的修改后的值,顯然不合情理。

(2)不可重複讀:在事務A中先後兩次讀取同一個數據,但是兩次讀取的結果不一樣。臟讀與不可重複讀的區別在於:前者讀到的是其他事務未提交的數據,後者讀到的是其他事務已提交的數據。

以上圖為例,事務A在先後讀取文章閱讀量的數據時,結果卻不一樣。說明事務A在執行的過程中,閱讀量的值被其它事務給修改了。這樣使得數據的查詢結果不再可靠,同樣也不合實際。

(3)幻讀:在事務A中按照某個條件先後兩次查詢數據庫,兩次查詢結果的行數不同,這種現象稱為幻讀。不可重複讀與幻讀的區別可以通俗的理解為:前者是數據變了,後者是數據的行數變了。

以上圖為例,當對0<閱讀量<100的文章進行查詢時,先查到了一個結果,後來查詢到了兩個結果。這表明同一個事務的查詢結果數不一,行數不一致。這樣的問題使得在根據某些條件對數據篩選的時候,前後篩選結果不具有可靠性。

隔離級別

根據上面這三種問題,產生了四種隔離級別,表明數據庫不同程度的隔離性質。

在實際的數據庫設計中,隔離級別越高,導致數據庫的併發效率會越低;而隔離級別太低,又會導致數據庫在讀寫過程中會遇到各種亂七八糟的問題。

因此在大多數數據庫系統中,默認的隔離級別時讀已提交(如Oracle)或者可重複讀RR(MySQL的InnoDB引擎)。

MVCC

又是一個難嚼的大塊頭。MVCC就是用來實現上面的第三個隔離級別,可重複讀RR。

MVCC:Multi-Version Concurrency Control,即多版本的併發控制協議。

MVCC的特點就是在同一時刻,不同事務可以讀取到不同版本的數據,從而可以解決臟讀和不可重複讀的問題。

MVCC實際上就是通過數據的隱藏列和回滾日誌(undo log),實現多個版本數據的共存。這樣的好處是,使用MVCC進行讀數據的時候,不用加鎖,從而避免了同時讀寫的衝突。

在實現MVCC時,每一行的數據中會額外保存幾個隱藏的列,比如當前行創建時的版本號和刪除時間和指向undo log的回滾指針。這裏的版本號並不是實際的時間值,而是系統版本號。每開始新的事務,系統版本號都會自動遞增。事務開始時的系統版本號會作為事務的版本號,用來和查詢每行記錄的版本號進行比較。

每個事務又有自己的版本號,這樣事務內執行數據操作時,就通過版本號的比較來達到數據版本控制的目的。

另外,InnoDB實現的隔離級別RR時可以避免幻讀現象的,這是通過next-key lock機制實現的。這裏簡單講講吧。

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

擁有後台管理系統的網站,將擁有強大的資料管理與更新功能,幫助您隨時新增網站的內容並節省網站開發的成本。

next-key lock實際上就是行鎖的一種,只不過它不只是會鎖住當前行記錄的本身,還會鎖定一個範圍。比如上面幻讀的例子,開始查詢0<閱讀量<100的文章時,只查到了一個結果。next-key lock會將查詢出的這一行進行鎖定,同時還會對0<閱讀量<100這個範圍進行加鎖,這實際上是一種間隙鎖。間隙鎖能夠防止其他事務在這個間隙修改或者插入記錄。這樣一來,就保證了在0<閱讀量<100這個間隙中,只存在原來的一行數據,從而避免了幻讀。

間隙鎖:封鎖索引記錄中的間隔

雖然InnoDB使用next-key lock能夠避免幻讀問題,但卻並不是真正的可串行化隔離。再來看一個例子吧。

首先提一個問題,在T6事務A提交事務之後,猜一猜文章A和文章B的閱讀量為多少?

答案是,文章AB的閱讀量都被修改成了10000。這代表着事務B的提交實際上對事務A的執行產生了影響,表明兩個事務之間並不是完全隔離的。雖然能夠避免幻讀現象,但是卻沒有達到可串行化的級別。

這還說明,避免臟讀、不可重複讀和幻讀,是達到可串行化的隔離級別的必要不充分條件。可串行化是都能夠避免臟讀、不可重複讀和幻讀,但是避免臟讀、不可重複讀和幻讀卻不一定達到了可串行化。

一致性

一致性是指事務執行結束后,數據庫的完整性約束沒有被破壞,事務執行的前後都是合法的數據狀態。

一致性是事務追求的最終目標:前面提到的原子性、持久性和隔離性,都是為了保證數據庫狀態的一致性。

這就不多說了吧。你細品。

4 MySQL日誌系統

了解完MySQL的基本架構,大體上能夠對MySQL的執行流程有了比較清晰的認知。接下來我將在講述MySQL事務之前,先為大家介紹以下日誌系統,以方便之後更好的理解事務的特性和實現。

MySQL日誌系統是數據庫的重要組件,用於記錄數據庫的更新和修改。若數據庫發生故障,可通過不同日誌記錄恢複數據庫的原來數據。因此實際上日誌系統直接決定着MySQL運行的魯棒性和穩健性。

MySQL的日誌有很多種,如二進制日誌(binlog)、錯誤日誌、查詢日誌、慢查詢日誌等,此外InnoDB存儲引擎還提供了兩種日誌:redo log(重做日誌)和undo log(回滾日誌)。這裏將重點針對InnoDB引擎,對重做日誌、回滾日誌和二進制日誌這三種進行分析。

重做日誌(redo log)

重做日誌(redo log)是InnoDB引擎層的日誌,用來記錄事務操作引起數據的變化,記錄的是數據頁的物理修改。

重做日記的作用其實很好理解,我打個比方。數據庫中數據的修改就好比你寫的論文,萬一哪天論文丟了怎麼呢?以防這種不幸的發生,我們可以在寫論文的時候,每一次修改都拿個小本本記錄一下,記錄什麼時間對某一頁進行了怎麼樣的修改。這就是重做日誌。

InnoDB引擎對數據的更新,是先將更新記錄寫入redo log日誌,然後會在系統空閑的時候或者是按照設定的更新策略再將日誌中的內容更新到磁盤之中。這就是所謂的預寫式技術(Write Ahead logging)。這種技術可以大大減少IO操作的頻率,提升數據刷新的效率。

臟數據刷盤

值得注意的是,redo log日誌的大小是固定的,為了能夠持續不斷的對更新記錄進行寫入,在redo log日誌中設置了兩個標誌位置,checkpointwrite_pos,分別表示記錄擦除的位置和記錄寫入的位置。redo log日誌的數據寫入示意圖可見下圖。

write_pos標誌到了日誌結尾時,會從結尾跳至日誌頭部進行重新循環寫入。所以redo log的邏輯結構並不是線性的,而是可看作一個圓周運動。write_poscheckpoint中間的空間可用於寫入新數據,寫入和擦除都是往後推移,循環往複的。

write_pos追上checkpoint時,表示redo log日誌已經寫滿。這時不能繼續執行新的數據庫更新語句,需要停下來先刪除一些記錄,執行checkpoint規則騰出可寫空間。

checkpoint規則:checkpoint觸發后,將buffer中臟數據頁和臟日誌頁都刷到磁盤。

臟數據:指內存中未刷到磁盤的數據。

redo log中最重要的概念就是緩衝池buffer pool,這是在內存中分配的一個區域,包含了磁盤中部分數據頁的映射,作為訪問數據庫的緩衝。

當請求讀取數據時,會先判斷是否在緩衝池命中,如果未命中才會在磁盤上進行檢索後放入緩衝池;

當請求寫入數據時,會先寫入緩衝池,緩衝池中修改的數據會定期刷新到磁盤中。這一過程也被稱之為刷臟

因此,當數據修改時,除了修改buffer pool中的數據,還會在redo log中記錄這次操作;當事務提交時,會根據redo log的記錄對數據進行刷盤。如果MySQL宕機,重啟時可以讀取redo log中的數據,對數據庫進行恢復,從而保證了事務的持久性,使得數據庫獲得crash-safe能力。

臟日誌刷盤

除了上面提到的對於臟數據的刷盤,實際上redo log日誌在記錄時,為了保證日誌文件的持久化,也需要經歷將日誌記錄從內存寫入到磁盤的過程。redo log日誌可分為兩個部分,一是存在易失性內存中的緩存日誌redo log buff,二是保存在磁盤上的redo log日誌文件redo log file

為了確保每次記錄都能夠寫入到磁盤中的日誌中,每次將redo log buffer中的日誌寫入redo log file的過程中都會調用一次操作系統的fsync操作。

fsync函數:包含在UNIX系統頭文件#include <unistd.h>中,用於同步內存中所有已修改的文件數據到儲存設備。

在寫入的過程中,還需要經過操作系統內核空間的os buffer。redo log日誌的寫入過程可見下圖。

二進制日誌(binlog)

二進制日誌binlog是服務層的日誌,還被稱為歸檔日誌。binlog主要記錄數據庫的變化情況,內容包括數據庫所有的更新操作。所有涉及數據變動的操作,都要記錄進二進制日誌中。因此有了binlog可以很方便的對數據進行複製和備份,因而也常用作主從庫的同步。

這裏binlog所存儲的內容看起來似乎與redo log很相似,但是其實不然。redo log是一種物理日誌,記錄的是實際上對某個數據進行了怎麼樣的修改;而binlog是邏輯日誌,記錄的是SQL語句的原始邏輯,比如”給ID=2這一行的a字段加1 “。binlog日誌中的內容是二進制的,根據日記格式參數的不同,可能基於SQL語句、基於數據本身或者二者的混合。一般常用記錄的都是SQL語句。

這裏的物理和邏輯的概念,我的個人理解是:

物理的日誌可看作是實際數據庫中數據頁上的變化信息,只看重結果,而不在乎是通過“何種途徑”導致了這種結果;

邏輯的日誌可看作是通過了某一種方法或者操作手段導致數據發生了變化,存儲的是邏輯性的操作。

同時,redo log是基於crash recovery,保證MySQL宕機后的數據恢復;而binlog是基於point-in-time recovery,保證服務器可以基於時間點對數據進行恢復,或者對數據進行備份。

事實上最開始MySQL是沒有redo log日誌的。因為起先MySQL是沒有InnoDB引擎的,自帶的引擎是MyISAM。binlog是服務層的日誌,因此所有引擎都能夠使用。但是光靠binlog日誌只能提供歸檔的作用,無法提供crash-safe能力,所以InnoDB引擎就採用了學自於Oracle的技術,也就是redo log,這才擁有了crash-safe能力。這裏對redo log日誌和binlog日誌的特點分別進行了對比:

在MySQL執行更新語句時,都會涉及到redo log日誌和binlog日誌的讀寫。一條更新語句的執行過程如下:

從上圖可以看出,MySQL在執行更新語句的時候,在服務層進行語句的解析和執行,在引擎層進行數據的提取和存儲;同時在服務層對binlog進行寫入,在InnoDB內進行redo log的寫入。

不僅如此,在對redo log寫入時有兩個階段的提交,一是binlog寫入之前prepare狀態的寫入,二是binlog寫入之後commit狀態的寫入。

之所以要安排這麼一個兩階段提交,自然是有它的道理的。現在我們可以假設不採用兩階段提交的方式,而是採用“單階段”進行提交,即要麼先寫入redo log,后寫入binlog;要麼先寫入binlog,后寫入redo log。這兩種方式的提交都會導致原先數據庫的狀態和被恢復后的數據庫的狀態不一致。

先寫入redo log,后寫入binlog:

在寫完redo log之後,數據此時具有crash-safe能力,因此系統崩潰,數據會恢復成事務開始之前的狀態。但是,若在redo log寫完時候,binlog寫入之前,系統發生了宕機。此時binlog沒有對上面的更新語句進行保存,導致當使用binlog進行數據庫的備份或者恢復時,就少了上述的更新語句。從而使得id=2這一行的數據沒有被更新。

先寫入binlog,后寫入redo log:

寫完binlog之後,所有的語句都被保存,所以通過binlog複製或恢復出來的數據庫中id=2這一行的數據會被更新為a=1。但是如果在redo log寫入之前,系統崩潰,那麼redo log中記錄的這個事務會無效,導致實際數據庫中id=2這一行的數據並沒有更新。

由此可見,兩階段的提交就是為了避免上述的問題,使得binlog和redo log中保存的信息是一致的。

回滾日誌(undo log)

回滾日誌同樣也是InnoDB引擎提供的日誌,顧名思義,回滾日誌的作用就是對數據進行回滾。當事務對數據庫進行修改,InnoDB引擎不僅會記錄redo log,還會生成對應的undo log日誌;如果事務執行失敗或調用了rollback,導致事務需要回滾,就可以利用undo log中的信息將數據回滾到修改之前的樣子。

但是undo log不redo log不一樣,它屬於邏輯日誌。它對SQL語句執行相關的信息進行記錄。當發生回滾時,InnoDB引擎會根據undo log日誌中的記錄做與之前相反的工作。比如對於每個數據插入操作(insert),回滾時會執行數據刪除操作(delete);對於每個數據刪除操作(delete),回滾時會執行數據插入操作(insert);對於每個數據更新操作(update),回滾時會執行一個相反的數據更新操作(update),把數據改回去。undo log由兩個作用,一是提供回滾,二是實現MVCC。

5 主從複製

主從複製的概念很簡單,就是從原來的數據庫複製一個完全一樣的數據庫,原來的數據庫稱作主數據庫,複製的數據庫稱為從數據庫。從數據庫會與主數據庫進行數據同步,保持二者的數據一致性。

主從複製的原理實際上就是通過bin log日誌實現的。bin log日誌中保存了數據庫中所有SQL語句,通過對bin log日誌中SQL的複製,然後再進行語句的執行即可實現從數據庫與主數據庫的同步。

主從複製的過程可見下圖。主從複製的過程主要是靠三個線程進行的,一個運行在主服務器中的發送線程,用於發送binlog日誌到從服務器。兩外兩個運行在從服務器上的I/O線程和SQL線程。I/O線程用於讀取主服務器發送過來的binlog日誌內容,並拷貝到本地的中繼日誌中。SQL線程用於讀取中繼日誌中關於數據更新的SQL語句並執行,從而實現主從庫的數據一致。

之所以需要實現主從複製,實際上是由實際應用場景所決定的。主從複製能夠帶來的好處有:

1 通過複製實現數據的異地備份,當主數據庫故障時,可切換從數據庫,避免數據丟失。

2 可實現架構的擴展,當業務量越來越大,I/O訪問頻率過高時,採用多庫的存儲,可以降低磁盤I/O訪問的頻率,提高單個機器的I/O性能。

3 可實現讀寫分離,使數據庫能支持更大的併發。

4 實現服務器的負載均衡,通過在主服務器和從服務器之間切分處理客戶查詢的負荷。

6 總結

MySQL數據庫應該算是程序員必須掌握的技術之一了。無論是項目過程中還是面試中,MySQL都是非常重要的基礎知識。不過,對於MySQL來說,真的東西太多了。我在寫這篇文章的時候,查閱了大量的資料,發現越看不懂的越多。還真是應了那句話:

你知道的越多,不知道的也就越多。

這篇文章着重是從理論的角度去解析MySQL基本的事務和日誌系統的基本原理,我在表述的時候盡可能的避免採用實際的代碼去描述。即便是這篇將近一萬字+近二十副純手工繪製的圖解,也難以將MySQL的博大精深分析透徹。

但是我相信,對於初學者而言,這些理論能夠讓你對MySQL有一個整體的感知,讓你對“何謂關係型數據庫”這麼一個問題有了比較清晰的認知;而對於熟練掌握MySQL的大佬來說,或許本文也能夠喚醒你塵封已久的底層理論基礎,對你之後的面試也會有一定幫助。

技術這種東西沒有絕對的對錯,倘若文中有誤還請諒解,並歡迎與我討論。自主思考永遠比被動接受更有效。

7 reference

https://www.cnblogs.com/kismetv/p/10331633.html

https://www.cnblogs.com/ivy-zheng/p/11094528.html

https://blog.csdn.net/qq_39016934/article/details/90116706

https://www.jianshu.com/p/5af73b203f2a

https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html#auto_id_2

微信搜索業餘碼農,閱讀更多技術隨筆。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※教你寫出一流的銷售文案?

銷售文案是什麼?A文案是廣告用的文字。舉凡任何宣傳、行銷、販賣商品時所用到的文字都是文案。在網路時代,文案成為行銷中最重要的宣傳方式,好的文案可節省大量宣傳資源,達成行銷目的。

國外零售商洩漏 Intel 第 11 代 Rocket Lake-S 處理器的售價,i9-11900K 價格比上一代便宜一些_網頁設計公司

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

台中景泰電動車行只是一個單純的理由,將來台灣的環境,出門可以自由放心的深呼吸,讓空氣回歸自然的乾淨,減少污染,留給我們下一代有好品質無空污的優質環境

先前 CES 2021 發表會上,Intel 正式透露第 11 代 Rocket Lake-S 處理器(i9-11900K)官方效能跑分之後,相信不少玩家都非常期待,不僅比上一代還強,也勝過對手的 AMD 12 核心 Ryzen 5900X,不過當時並沒有公布售價,也因此想買的人究竟該準備多少,只能參考第 10 代的價格。最近國外就有一間零售商,疑似搶先放上第 11 代 Rocket Lake-S 處理器的價格列表,從 i9、i7、一直到 i5 都有,有些比較貴,有些便宜。

國外零售商洩漏 Intel 第 11 代 Rocket Lake-S 處理器的售價

近日比利時一間 2Compute 電腦硬體零售商在它的官網上,洩漏第 11 代 Rocket Lake-S 處理器的價格列表,而且現在還沒刪除,感覺就像是故意放上去一樣。

根據列表顯示,新一代遊戲旗艦處理器 8 核心 16 執行緒的 i9-11900K 單顆未稅價為 499.70 歐元,含稅之後變成 605 歐元,代表說比上一代 i9-10900K 還便宜 9.8% 左右。

下圖是 i9-11900K 的價格:

i9-10900K 的價格,單顆未稅價 549 歐元,含稅之後 665 歐元:

下方為第 11 代 Rocket Lake-S 處理器與第 10 代 Comet Lake-S 處理器的比較圖,i9-11900KF 也比上一代便宜,但 i9-11900 與 i9-11900F 就沒有,其餘 i7、i5 大多數也比上一代貴:

2Compute 網站洩漏的 Rocket Lake-S 處理器價格清單(含稅價):

  • i5-11400:205 歐元
  • i5-11400F:175 歐元
  • i5-11500:227 歐元
  • i5-11600:250 歐元
  • i5-11600K:294 歐元
  • i5-11600KF:265 歐元
  • i7-11700:371 歐元
  • i7-11700F:342 歐元
  • i7-11700K:456 歐元
  • i7-11700KF:427 歐元
  • i9-11900:494 歐元
  • i9-11900F:465 歐元
  • i9-11900K:605 歐元
  • i9-11900KF:576 歐元

如果比較整體價格,第 11 代 Rocket Lake-S 處理器平均大約比第 10 代 Comet Lake-S 處理器貴 14% 左右。當然,這是零售商搶先洩漏的清單,也因此一切還是要以 Intel 官方為主。

Intel 第 11 代 Rocket Lake-S 處理器預計會在 3 月正式推出,下個月應該會有更確切的消息出現。

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網站的第一印象網頁設計,決定了客戶是否繼續瀏覽的意願。台北網動廣告製作的RWD網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上它。

有趣的是,除了 2Compute,國外其實還有其他零售商也洩漏這價格清單,不過大家都不太一樣,讓人看起來有點亂:

Intel 11th Gen Price

10th Gen sheet is for comparison pic.twitter.com/kAvMbIQjKm

— 포시포시 (@harukaze5719) January 17, 2021

資料來源:Video Cardz

Intel 第 11 代「Rocket Lake」與第 12 代「Alder Lake」搶先看

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

以設計的實用美學觀點,規劃出舒適、美觀的視覺畫面,有效提昇使用者的心理期待,營造出輕鬆、愉悅的網站瀏覽體驗。

[C#.NET 拾遺補漏]01:字符串操作_網頁設計公司

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

字符串操作在任意編程語言的日常編程中都隨處可見,今天來匯總一下 C# 中關於字符串的一些你可能遺忘或遺漏的知識點。

逐字字符串

在普通字符串中,反斜杠字符是轉義字符。而在逐字字符串(Verbatim Strings)中,字符將被編程器按照原義進行解釋。使用逐字字符串只需在字符串前面加上 @ 符號。

// 逐字字符串:轉義符
var filename = @"c:\temp\newfile.txt";
Console.WriteLine(filenaame);

// 逐字字符串:多行文本
var multiLine = @"This is a
multiline paragraph."
;
Console.WriteLine(multiLine);

// 非逐字字符串
var escapedFilename = "c:\temp\newfile.txt";
Console.WriteLine(escapedFilename);

輸出:

c:\temp\newfile.txt
This is a
multiline paragraph.
c: emp
ewfile.txt

逐字字符串中唯一不被原樣解釋的字符是雙引號。由於雙引號是定義字符串的關鍵字符,所以在逐字字符串中要表達雙引號需要用雙引號進行轉義。

varstr = @"""I don't think so"", he said.";
Console.WriteLine(str);
// 輸出:"I don't think so", he said.

在逐字字符串中也可以 $ 符號實現字符串內插值。

Console.WriteLine($@"Testing \n 1 2 {5 - 2}");
// 輸出:Testing \n 1 2 3

数字格式化轉換

典型的的格式化方法為:

string.Format("{index[:format]}", number)

可使用“0”和“#”佔位符進行補位。“0” 表示位數不夠位數就補充“0”,小數部分如果位數多了則會四舍五入;“#”表示佔位,用於輔助“0”進行補位。

標準格式化用法:

// “0”描述:佔位符,如果可能,填充位
string.Format("{0:000000}",1234); // 結果:001234

// “#”描述:佔位符,如果可能,填充位
string.Format("{0:######}",1234); // 結果:1234
string.Format("{0:#0####}",1234); // 結果:01234
string.Format("{0:0#0####}",1234); // 結果:0001234

// "."描述:小數點
string.Format("{0:000.000}", 1234); // 結果:1234.000
string.Format("{0:000.000}", 4321.12543); // 結果:4321.125

// ","描述:千分表示
string.Format("{0:0,0}", 1234567); //結果:1,234,567

// "%"描述:格式化為百分數
string.Format("{0:0%}",1234); // 結果:123400%
string.Format("{0:#%}", 1234.125); // 結果:123413%
string.Format("{0:0.00%}",1234); // 結果:123400.00%
string.Format("{0:#.00%}",1234.125); // 結果:123412.50%

內置快捷字母格式化用法:

// E-科學計數法表示
(25000).ToString("E"); // 結果:2.500000E+004

// C-貨幣表示,帶有逗號分隔符,默認小數點后保留兩位,四舍五入
(2.5).ToString("C"); // 結果:¥2.50

// D[length]-十進制數
(25).ToString("D5"); // 結果:00025

// F[precision]-浮點數,保留小數位數(四舍五入)
(25).ToString("F2"); // 結果:25.00

// G[digits]-常規,保留指定位數的有效数字,四舍五入
(2.52).ToString("G2"); // 結果:2.5

// N-帶有逗號分隔符,默認小數點后保留兩位,四舍五入
(2500000).ToString("N"); // 結果:2,500,000.00

// X-十六進制,非整型將產生格式異常
(255).ToString("X"); // 結果:FF

ToString 也可以自定義補零格式化:

(15).ToString("000");              // 結果:015
(15).ToString("value is 0"); // 結果:value is 15
(10.456).ToString("0.00"); // 結果:10.46
(10.456).ToString("00"); // 結果:10
(10.456).ToString("value is 0.0"); // 結果:value is 10.5

轉換為二進制、八進制、十六進制輸出:

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

int number = 15;
Convert.ToString(number, 2); // 結果:1111
Convert.ToString(number, 8); // 結果:17
Convert.ToString(number, 16); // 結果:f

自定義格式化器:

public class CustomFormat : IFormatProvider, ICustomFormatter
{
public string Format(string format, object arg, IFormatProvider formatProvider)
{
if (!this.Equals(formatProvider))
{
return null;
}
if (format == "Reverse")
{
return string.Join("", arg.ToString().Reverse());
}
return arg.ToString();
}

public object GetFormat(Type formatType)
{
return formatType == typeof(ICustomFormatter) ? this : null;
}
}

使用自定義格式化器:

String.Format(newCustomFormat(), "-> {0:Reverse} <-", "Hello World");
// 輸出:-> dlroW olleH <-

字符串拼接

將數組中的字符串拼接成一個字符串:

var parts = new[] { "Foo", "Bar", "Fizz", "Buzz"};
var joined = string.Join(", ", parts);
// joined = "Foo, Bar, Fizz, Buzz"

以下四種方式都可以達到相同的字符串拼接的目的:

string first = "Hello";
string second = "World";
string foo = first + " " + second;
string foo = string.Concat(first, " ", second);
string foo = string.Format("{0} {1}", firstname, lastname);
string foo = $"{firstname} {lastname}";

字符串內插法

簡單用法:

var name = "World";
var str =$"Hello, {name}!";
// str = "Hello, World!"

帶日期格式化:

var date = DateTime.Now;
var str = $"Today is {date:yyyy-MM-dd}!";

補齊格式化(Padding):

var number = 42;

// 向左補齊
var str = $"The answer to life, the universe and everything is {number, 5}.";
// str = "The answer to life, the universe and everything is ___42." ('_'表示空格)

// 向右補齊
var str = $"The answer to life, the universe and everything is ${number, -5}.";
// str = "The answer to life, the universe and everything is 42___."

結合內置快捷字母格式化:

var amount = 2.5;
var str = $"It costs {amount:C}";
// str = "¥2.50"

var number = 42;
var str = $"The answer to life, the universe and everything is {number, 5:f1}.";
// str = "The answer to life, the universe and everything is ___42.1"

參考:

1.《C# 7.0 in a Nutshell》

2. https://bit.ly/2U1eIK9

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

如何選出適合自己的管理Helm Chart的最佳方式?_網頁設計公司

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網站的第一印象網頁設計,決定了客戶是否繼續瀏覽的意願。台北網動廣告製作的RWD網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上它。

作者:Merlin Carter,專註於早期創業公司的風險投資家,擅長撰寫開發人員創新和新技術的文章

原文鏈接:
https://insights.project-a.com/whats-the-best-way-to-manage-helm-charts-1cbf2614ec40

本文轉載自Rancher Labs

無論你喜歡與否,你都不得不承認Helm是管理Kubernetes應用程序獨一無二的工具,你甚至可以通過不同的方式使用它。

在Helm的使用過程中,我們注意到有幾個問題不斷出現:

  • 你將你的Helm chart放在哪裡?

你是使用app文件保存它們還是使用chart倉庫?

  • 你如何劃分Helm chart?

你是使用一個共享的chart或是為每個服務維護一個chart?

我正在通過我以往在各種創業公司的經驗來嘗試解決這些問題,但是我也借鑒了大型公司的做法。

以下是我要概述的幾個方法:

  1. 使用一個chart倉庫來存儲一個大型共享chart

  2. 使用一個chart倉庫來存儲許多特定於服務的chart

  3. 使用特定於服務的chart,這些chart與服務本身存儲在同一倉庫中

然後,我將介紹在決定這些選項時應該考慮的因素,例如依賴項差異和團隊結構等。

Option1:在一個chart倉庫中維護一個大型共享chart

在我們一個項目中,我們從一個用於部署多個服務的大型chart開始。它存儲在ChartMuseum中,並由負責部署基礎架構的人員進行維護。

如果你的各個服務在本質上十分類似,那麼共享chart可以為你省去很多麻煩。這裏我們採用Helm維護者Josh Dolitsky在KubeCon 2019上描述的情況:

我最近在負責一個項目,這個項目包含9個微服務……我意識到它們幾乎都是相同的HTTP監聽服務。所以我決定僅僅構建一個helm chart來部署9個不同的服務,為每個服務做不同的配置——僅為特定的服務設置一個新的docker標籤。

在這種情況下,將Helm chart存儲在ChartMuseum等chart倉庫中是有意義的,因為只有值需要保存在這些特定服務的倉庫中。

Option2:在一個chart倉庫中維護幾個特定於服務的chart

特定於服務的chart優勢在於,你可以更改一項服務,而無需擔心會破壞另一項服務。但是它們可能會導致重複的工作——如果你要更新通用配置,則必須在每個chart中進行相同的更改。

是否需要在一個chart倉庫中保存它們則是另一個問題了。如果這些chart是特定於服務的,那麼將它們存儲在一起尚沒有強有力的架構論證。當然,如果你有專門的人員或團隊來維護所有的chart,一起存儲多個特定於服務的chart通常會比較容易。

例如,與我一起工作的一位DevOps工程師,他在一个中心chart倉庫中維護15種不同的微服務chart。對於他而言,在同一個位置更新所有chart比向15個不同的倉庫提交拉取請求要容易得多。開發人員當然清楚如何更新chart,但是處理資源相關的設置顯然更吸引他們。

Option3:在與服務本身相同的倉庫種維護特定於服務的chart

對於基於微服務的應用程序來說,特定於服務的chart是一個很好的選擇。而當你將每個chart與服務代碼保存在同一倉庫中時,使用特定於服務的chart則會更好。

如果你在服務倉庫中存儲Helm chart,那麼可以更輕鬆地獨立於其他項目持續部署服務。並且你可以將chart更新(例如添加新變量)與應用程序邏輯的更改一起提交,使其更易於識別和還原重大更改。

然而,本選項的優勢取決於你所維護的微服務的數量。如果你的微服務數量正邁入兩位數,那麼這一選項的優勢則沒有那麼明顯,更多的是阻礙。如果你要處理非常同質的服務(如Josh Dolisky),則尤其如此。

決定選項時需要考慮的因素

一般情況下,有兩個方面需要考慮:

  • 依賴項和可重現:每個服務的依賴項有多少區別?對一個服務的更改有多大風險會中斷另一個服務?你如何再現特定的開發條件?

  • 團隊結構:你負責每個服務的小型自治團隊嗎?你有了解DevOps的開發人員嗎?你的團隊中DevOps文化流行程度如何?

依賴項和可重現

如果你將你的chart和應用程序分開維護,它們的版本將彼此不同。如果你在部署時遇到問題,並且需要重現導致該問題的條件,則需要確定:a)服務版本;b)用於部署它的chart版本。你可能想要走捷徑,使用“latest” chart來測試服務x.x.x,但這並不是一個好想法,因為這樣你將永遠無法重現造成問題的確切條件。

那麼,如果你經常需要更改的chart版本怎麼辦?是不是應該一起測試這些改動呢?

考慮到許多開發人員需要創建同一共享chart中的分支版本這一場景:

開發人員(圖中的Edeltraud和Eberhardt)分別在不同的分支中工作,並且想要在開發環境中測試他們的更改以及圖表更改——所以他們還需要分支chart。同時,DevOps工程師在他的共享chart的分支中更新一些常用組件。

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

以設計的實用美學觀點,規劃出舒適、美觀的視覺畫面,有效提昇使用者的心理期待,營造出輕鬆、愉悅的網站瀏覽體驗。

如果沒有人將他們的chart更改更新到各個分支,那麼就有可能破壞另一個服務部署。

不久前,我們正好遇到了這個問題。Chart維護者用一個新的條件塊更新了共享chart。該語句檢查了一個新的變量“foo”是否被設置為“啟用”。然而,變量“foo”還沒有在所有服務的值文件中定義。對於缺少該變量的服務,部署中斷了。不幸的是,當時chart中沒有定義默認的回滾行為。

如果chart和代碼位於同一個倉庫中,並且可以在同一個分支中進行測試,則針對這些問題的測試將更加容易。

即使一開始似乎是矯枉過正,我們也會這樣做。我們的工作對象是很少有依賴項的服務。對於每個服務,Helm chart只部署一個帶有特定Docker標籤的主容器。chart的名稱和docker標籤是通過變量傳遞進來的。儘管如此,我們仍然避免了使用共享chart,而是選擇在每個服務倉庫中放置單獨的chart。

這主要是因為我們只處理了四個服務。但我們的開發人員也更喜歡掌控所有能夠影響CI/CD的配置。然而情況並非總是如此,所以現在是研究另一個維度的好時機。

團隊結構

Chart維護的問題同時也取決於誰管理部署流程。

這裏推薦另一篇文章,由Helm維護者Matt Farina撰寫的,在文章中他闡述了關於Helm正在嘗試解決複雜性的話題。文章鏈接:

https://codeengineered.com/blog/2018/helm-kustomize-complexity/

他闡明了必須處理Kubernetes複雜性的三個主要角色。為了清楚起見,我將對其內容進行一些解釋,並將角色描述如下:

  1. App開發人員——這個角色主要構建服務、添加特性以及修復bug

  2. Deployer——這個角色負責將應用程序推向世界。理想情況下,有一個不錯的自動化程序可以為他們部署應用程序,但是他們知道它的工作方式,可以根據需要進行修改。

  3. 系統工程師——這一角色負責維護deployer部署的Kubernetes環境。他們是管理計算機資源的專家,並且可以盡量減少任何服務的停機時間。

第一個和第三個角色你都能在公司里找到與其負責內容相符的職位,而Deployer這個角色則有些模糊,這個角色所負責的內容常常會被其他兩個角色的人接管——這會影響你如何管理你的Helm chart。

尚在早期階段的初創公司的DevOps

如前所述,我們的業務是為初創企業提供運維支持,這些企業往往需要快速擴大規模。我們見過很多“非常規”的設置和分工。在早期階段,App開發者可能會負責各種事情,有些人甚至會幫忙完成系統管理員的任務,比如設置打印機或配置辦公室網絡等。他們會儘力去了解其他兩個角色所需要負責的內容,因為沒有人可以幫助他們(直到我們參与進來)。

一旦他們想了解Helm,大多數應用開發者會把他們的chart放在最容易處理的地方——也就是他們維護的同一個repo。

在大型企業中的DevOps

你可能在一個更大的、架構更分明的團隊中工作,

在這種情況下,你可能有自己的DevOps工程師甚至是整個DevOps部門。而這個人或團隊經常會覺得自己也要負責 “Deployer”的角色。很有可能,他們會傾向於採用更集中的方法,比如將所有的chart存儲在ChartMuseum這樣的chart倉庫中。更不願意讓應用開發者過多地參与到Helm chart中來(往往是有合理緣由的)。

例如,我最近看了一個經典的技術講座,叫《從頭開始構建Helm chart》,由VMWare系統工程師Amy Chen主講。在她的開場白中,她說:

在基礎設施方面,你的主要目標是時刻準備着應對故障,沒有信任——在這個意義上說,就像我不太願意信任我的APP開發者,並且我也不太需要信任我的APP開發者。

這是可以理解的。你不想讓應用開發者去搞亂設置,比如CPU和內存限制,或者是pod中斷預算。但整個 “DevOps文化”的概念是專門為了改善基礎設施維護者和開發者之間有時會出現的疏離關係而演化出來的。

實踐DveOps文化

Atlassian(JIRA和Trello的所有者)出版了一本“團隊手冊”,其中定義了DevOps文化:

DevOps文化是關於開發者和運維之間的共同理解,併為他們所構建的軟件分擔責任。這意味着增加透明度、溝通和協作,並在開發、IT/運維和 “業務”之間進行合作。

如果將其實際應用到Helm chart維護和一般的基礎架構配置中,就會把大部分的責任放在應用開發者的手中。他們也會承擔起“Deployer”的角色,並改變他們擁有的倉庫中的配置。

系統工程師仍然可以把他們專門維護的設置集中起來。例如,一些團隊也會維護一个中央基礎架構repo,該repo中保存着Terraform配置或Helm文件等常用資源,這些資源是啟動新項目所需要的(例如,用於設置ingress controller和cert manager)。Helm 3還支持所謂的 “library chart”,它只能作為另一個chart的一部分進行部署。這讓我們更容易區分常見的和服務特定的變更責任。

即使當chart存儲在服務倉庫中,系統工程師仍然可以作為重要更改的把關人。例如,你可以使用GitHub CODEOWNERS文件來確保系統工程師在你的repo中的chart目錄中的任何更改都會被添加為審核者。

如果系統工程師需要主動做一些與應用開發無關的改動,可以指導開發人員為他們做更改,並解釋為什麼這些改動是必須的。以下圖片也許能反映這種情況:

開發者可以了解更多關於基礎設施的內容以及這些更改如何影響他們的服務。

經驗法則

如果有簡單的經驗法則,那就是:先了解選項3。嘗試為服務倉庫中的每個服務維護一個Helm chart。或者至少考慮一下我之前描述的混合方法。

如果你有幾十個服務都非常相似,那麼共享chart是更好的選擇。只是要記住,你必須把它維護在一个中心repo中。但是這增加了意外耦合的風險,可能會破壞一個服務部署。風險增加意味着你在部署的時候需要更加謹慎,這反過來又意味着你會減少部署的頻率。

即使你有特定服務的chart,你可能也需要集中存儲,因為你沒有足夠的人員或專業知識以分佈式的方式來管理這些chart。或者,也許你的團隊需要在“Deployer”和“應用開發者”之間明確劃分責任。

無論你決定做什麼,我希望我已經說明清楚了你在做最後決定時需要考慮的問題。做一個“Deployer”並不容易,尤其是當它不是你的日常工作時。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

台中景泰電動車行只是一個單純的理由,將來台灣的環境,出門可以自由放心的深呼吸,讓空氣回歸自然的乾淨,減少污染,留給我們下一代有好品質無空污的優質環境

20多萬預算 90%的人不會考慮買這些車 這到底是為什麼?_網頁設計公司

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

台中景泰電動車行只是一個單純的理由,將來台灣的環境,出門可以自由放心的深呼吸,讓空氣回歸自然的乾淨,減少污染,留給我們下一代有好品質無空污的優質環境

99萬東風日產-西瑪售價:23。48-26。78萬沃爾沃亞太-沃爾沃S60L售價:26。69-55。99萬總結:目前來說,大眾邁騰、奧迪A4L、本田雅閣等傳統中級車,在市場的統治地位仍然牢不可破。但隨着消費升級和多元化需求的高漲,有個性有實力的中級車更容易贏得一部分人的青睞,而推薦的這四款轎車恰好做到了。

現在汽車市場的同質化情況可謂是愈來愈嚴重,擺在競爭激烈的中級車市場更是如此。但是,對於購買中級車的潛在用戶來說,

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網站的第一印象網頁設計,決定了客戶是否繼續瀏覽的意願。台北網動廣告製作的RWD網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上它。

價格因素不再是首要的,產品力才是關鍵。隨着各大品牌在中級車領域各顯神通,一些有個性、有顏值以及有實力的中級車,逐漸獲得了更多用戶的認可。

一汽馬自達-阿特茲

售價:17.58-23.98萬

東風雪鐵龍C6

售價:18.99-27.99萬

東風日產-西瑪

售價:23.48-26.78萬

沃爾沃亞太-沃爾沃S60L

售價:26.69-55.99萬

總結:目前來說,大眾邁騰、奧迪A4L、本田雅閣等傳統中級車,在市場的統治地位仍然牢不可破。但隨着消費升級和多元化需求的高漲,有個性有實力的中級車更容易贏得一部分人的青睞,而推薦的這四款轎車恰好做到了。那麼問題來了,你們最喜歡哪一款呢?本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

以設計的實用美學觀點,規劃出舒適、美觀的視覺畫面,有效提昇使用者的心理期待,營造出輕鬆、愉悅的網站瀏覽體驗。

跨11國、7000公里 「天鵝人」乘飛行傘追候鳥遷徙 新任務將跟飛魚鷹_網頁設計公司

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

以設計的實用美學觀點,規劃出舒適、美觀的視覺畫面,有效提昇使用者的心理期待,營造出輕鬆、愉悅的網站瀏覽體驗。

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網站的第一印象網頁設計,決定了客戶是否繼續瀏覽的意願。台北網動廣告製作的RWD網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上它。

疑似小米手環 6 規格與新功能現身!加入血氧飽和偵測、GPS、更多運動模式_網頁設計公司

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網站的第一印象網頁設計,決定了客戶是否繼續瀏覽的意願。台北網動廣告製作的RWD網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上它。

現在基本上每一年,小米都會更新旗下非常受歡迎的小米手環系列,今年沒意外應該有機會看到小米手環 6,而離小米手環 5 發表時間也有半年左右,最近終於有相關消息出現了!外媒從一款智慧手環 App 程式碼中,發現一個設備型號「XMSH16HM」疑似是小米手環 6,內容還透露一些規格與新功能,像是 GPS 與血氧濃度偵測等等,有興趣深入瞭解的人,他們也有把文件分享出來。

疑似小米手環 6 規格與新功能現身

根據外媒 LOGGER 報導,近日他們在 Zepp 智慧手環 App 的程式碼中,找到一個以 Pangu 作為代號的設備,型號則是 「XMSH16HM」,韌體文件也顯示 Pangu 是 Mi Smarrt Band 6 的代碼:

除了 XMSH16HM 之外,還能找到另一個 XMSH15HM 的型號,看起來應該是有沒有 NFC 的差別:

功能與規格部分,程式碼中顯示這款設備將會搭載 GPS 功能,另外還有 SpO2 血氧濃度偵測,可說讓人相當期待:

另外錶盤與一些圖示看起來都會重新設計,下面幾個是新款小米手環出現的新動畫:

小米手環 6 的錶盤寬度似乎是 152px,高度則介於 360px 至 370px 之間,因此預計錶盤預覽圖片會比小米手環 5 還要大:

從資源文件中還發現到,小米手環 6 已經有 308 個表情符號,意味著未來可能不用再自行安裝任何東西,原生就支援顯示表情符號:

LOGGER 也提到,跟小米手環 5 相比,新款小米手環更多應用都會有自己的通知圖示:

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

台中景泰電動車行只是一個單純的理由,將來台灣的環境,出門可以自由放心的深呼吸,讓空氣回歸自然的乾淨,減少污染,留給我們下一代有好品質無空污的優質環境

功能圖示:

小米手環 5 已經提供高達 11 種運動模式,但從這份文件的運動圖示來看,小米手環 6 似乎會再增加:

Zepp 是由華米開發的智慧手環 App,看起來可信度相當高,LOGGER 也有把文件分享出來,有興趣的人可以點我跳轉。不過畢竟只是程式碼,再加上離小米手環 6 可能推出還有半年時間,功能與規格還是有可能會變動,未來有任何新消息我們也會隨時追蹤。

資料來源:LOGGER

千元有找小米手環 5 開箱實測,涵蓋 11 種運動模式、多項健康功能再升級

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

以設計的實用美學觀點,規劃出舒適、美觀的視覺畫面,有效提昇使用者的心理期待,營造出輕鬆、愉悅的網站瀏覽體驗。

Web 三維組態的仿真運用案例:民航飛機的數據監控_網頁設計公司

※想知道最厲害的網頁設計公司嚨底家"!

RWD(響應式網頁設計)是透過瀏覽器的解析度來判斷要給使用者看到的樣貌

前言 在飛機航行的過程中,客艙里座位上方的熒屏上,除了播放電視劇和廣告之外,還會時不時的切換到一個飛機航行的監控系統。這個監控系統的主要目的是,讓乘客可以了解到飛機在航行過程中的整體狀況、距離目的地的航線進程以及一些有可能出現的突發事件。飛機航行的監控系統在一定程度上,可以使乘客在旅途過程中得到準確的信息源,最重要的是可以使乘客在旅途中得到安心。在保障乘客獲取到實際信息源的同時,飛機航行的監控系統也能將採集到的數據及時的反饋給航務人員,而且將數據記錄保存下來,在飛機過站或航后供航務和機務人員使用和監測維護。介於 2D 組態和 3D 組態上,
Hightopo(以下簡稱 HT )的 
HT for Web 產品上的有着豐富的組態化可供選擇,本文將介紹如何運用 HT 豐富的 
2/3D 組態搭建出一個飛機航行的監控系統的解決方案。 預覽地址: flight-monitor  
系統分析 飛機航行監控是一種測量、跟蹤飛機性能變化趨勢的簡單而實用方法。在日常航班飛行中,用機載儀錶記錄飛機巡航時的有關參數,並將其與原有性能進行比較。監控的主要參數有:飛行單位時間消耗的燃油量、飛機的巡航飛行速度和消耗單位燃油量飛機飛過的水平距離。它們分別表示發動機、飛機及飛機發動機的綜合性能。它們分別表示發動機、飛機及飛機發動機的綜合性能。性能監控的結果,既可為飛機維修提供可能的故障信息,又為制定飛行計劃提供可靠的性能依據。 目前,先進的噴氣運輸機都已安裝飛行狀態監控系統,它記錄下有關參數值,並存儲在數據管理裝置中,這些數據可以發送到或在飛機着陸後送到地面站,用專用計算機程序進行計算和修正,使性能監控數據採集、發送、計箅分析工作自動化,節省了人力,提高了精確度。 1、
飛行數據記錄器:自從飛行數據記錄器 FDR(Flight Data Recorder)“俗稱黑匣子”誕生以來,其提供的詳實準確的飛行數據為事故調查、機務維護保障、安全運營監控提供了重要依據,成為航空安全運營的重要管理手段。 2、
ACMS(Aireraft Condition Monitoring System)的系統概述:ACMS 系統是飛機上安裝的先進機載數據採集和處理系統,它能以實時方式收集數據,對發動機狀態和飛行性能進行監控以及進行特殊的工程調查。由飛機通信尋址與報告系統(ACARS)通過地空數據鏈發送到地面接收站,最後傳送到航空公司的終端,也可通過快速存取記錄器(QAR)將數據記錄保存下來,在飛機過站或航后供航務和機務人員使用。 而 HT 實現的業務功能可以通過ACMS 系統採集到的數據,對接到显示終端去展示,通過實時監測的數據準確地显示出來,起到對飛機狀態的監控功能並即時反饋信息數據的變化。  
實現過程
雲中穿行效果 為了達到飛機雲中穿行的效果,最開始我遇到的問題是飛機飛行的層次感,也就通常所說的透視效果,這裏我採用的是雲通道和雲背景以不同的速度流動,製造一種飛行的透視效果。   雲我採用的是貼圖的方式呈現的,但是僅僅是貼圖會遮擋天空和飛機,非常影響飛機飛行的觀感,所以我開啟了相應圖元的 
transparent 和 
opacity,雲背景和雲通道設置不同的透明度,不僅增加了層次感,還會讓人產生雲朵從眼前飄過的錯覺。   雲通道採用的是 
ht.Polyline 類型,通道縮放拉大了 Y 軸的比例,使雲通道有更大的縱向空間,設置 
reverse.flip 背拷貝使雲通道內部也显示出貼圖,彷彿讓飛機置身於雲海中穿梭;雲背景採用 
ht.Node 類型,只設置一個面显示充當雲背景。   整體的雲流動效果採用 
offset 偏移實現,改變相應圖元或相應圖元面的貼圖偏移量來達到飛機雲中穿行的效果, 代碼如下:

var i = 1, p = 0; setInterval(() => { i -= 0.1; p += 0.005; clouds.s('shape3d.uv.offset', [i, 0]); cloudBackground.s('all.uv.offset', [p, 0]); }, 100);

 

升降顛簸效果 雖然達到了飛機雲中穿行的效果,但是如果飛機只是直直的飛行,那也會降低飛行的實感,相信坐過飛機的朋友肯定都遇到過因氣流產生的顛簸,也經常感受到飛機飛行途中的爬升和下降,這其實是因為飛機的航線並不是一直固定在一個高度上,有時會爬升有時會下降,所以我就用 
ht-animation.js HT 動畫擴展插件去實現飛機顛簸效果,代碼如下:

dm.enableAnimation(20);
plane.setAnimation({
    back1: {
        from: 0, to: 160, easing: 'Cubic.easeInOut', duration: 8000, next: "up1", onUpdate: function (value) { value = parseInt(value); var p3 = this.p3(); this.p3(value, p3[1], p3[2]); } }, //...省略相似 start: ["back1"] });

 

球扇形視角限制 飛行效果完善之後,這時我就遇到了一個比較棘手的問題,因為實際上雖然看着飛機是在雲海中穿梭,但是僅僅是在通道中飛行,背景其實也只是平面貼圖,所以當視角到達某種程度的時候就會有強烈的違和感和不真實感,就需要一個視角限制,使視角的調整剛剛好在一個範圍內。   視角限制的話一般是限制 g3d 的 
eye 和 
center,不太了解的朋友可以去看 hightopo 官網中的 3d 手冊,裏面有詳細的說明,這裏我就不再贅述了;因為視角範圍的關係,所以我決定固定 
center 的位置,代碼如下:

g3d.addPropertyChangeListener(e => {
    // 固定中心點 if (e.property === 'center') { e.newValue[0] = center[0]; e.newValue[1] = center[1]; e.newValue[2] = center[2]; } }

然後再把 eye 限制在某一個範圍內就大功告成了,然而這裏卻並不是那麼簡單,最開始我把 eye 限制在一個立方體的空間內,但交互效果很不理想,考慮到 g3d 默認交互中,鼠標拖拽平移視角變換時,實際上 eye 是在一個以 center 為球心的球面上運動的,所以我決定從這個球中挖出來一塊作為 eye 的限制空間,也就是球扇形,不太理解的朋友可以參考這個圖:

 

球扇形視角限制,一共需要三個參數,分別是中心參考軸、中心軸和外邊所成角度、所在球限制半徑,其中中心參考軸可根據初始 eye 和 center 的連接延長線確定,所在球限制半徑又分最大限制和最小限制,代碼如下:

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

透過資料庫的網站架設建置,建立公司的形象或購物系統,並提供最人性化的使用介面,讓使用者能即時接收到相關的資訊

function limitEye(g3d, eye, center, options) { var limitMaxL = options.limitMaxL, limitMinL = options.limitMinL, limitA = options.limitA; g3d.addPropertyChangeListener(e => { // 固定中心點 if (e.property === 'center') { e.newValue[0] = center[0]; e.newValue[1] = center[1]; e.newValue[2] = center[2]; } // 限制視角 if (e.property === 'eye') { var newEyeV = new ht.Math.Vector3(e.newValue), centerV = new ht.Math.Vector3(center), refEyeV = new ht.Math.Vector3(eye), refVector = refEyeV.clone().sub(centerV), newVector = newEyeV.clone().sub(centerV); if (centerV.distanceTo(newEyeV) > limitMaxL) { newVector.setLength(limitMaxL); e.newValue[0] = newVector.x; e.newValue[1] = newVector.y; e.newValue[2] = newVector.z; } if (centerV.distanceTo(newEyeV) < limitMinL) { newVector.setLength(limitMinL); e.newValue[0] = newVector.x; e.newValue[1] = newVector.y; e.newValue[2] = newVector.z; } if (newVector.angleTo(refVector) > limitA) { var oldLength = newVector.length(), oldAngle = newVector.angleTo(refVector), refLength = oldLength * Math.cos(oldAngle), vertVector, realVector, realEye; refVector.setLength(refLength); newEyeV = newVector.clone().add(centerV); refEyeV = refVector.clone().add(centerV); vertVector = newEyeV.clone().sub(refEyeV); vertLength = refLength * Math.tan(limitA); vertVector.setLength(vertLength); realVector = vertVector.clone().add(refEyeV).sub(centerV); realVector.setLength(oldLength); realEye = realVector.clone().add(centerV); // 防止移動角度大於 180 度,視角反轉 if (oldAngle > Math.PI / 2) { realEye.negate(); } e.newValue[0] = realEye.x; e.newValue[1] = realEye.y; e.newValue[2] = realEye.z; } } }) }

 

飛機監控系統 當然作為監控系統,自然要有監控了,增加右下角的小地圖,並提供三種模式,分別是聚焦飛機,聚焦飛行軌跡和聚焦地圖,並根據飛機的飛行方向控制飛行軌跡的流動效果,其中聚焦飛機會跟隨飛機移動進行 
fitData,使飛機一直處於小地圖的中心,代碼如下:

var fitFlowP = function (e) { if (e.property === 'position' && e.data === plane) { mapGV.fitData(plane, false); } }; buttonP.s({ 'interactive': true, 'onClick': function (event, data, view, point, width, height) { map.a('fitDataTag', 'plane2D'); mapGV.fitData(plane, false); mapDM.md(fitFlowP); } }); buttonL.s({ 'interactive': true, 'onClick': function (event, data, view, point, width, height) { mapDM.umd(fitFlowP); map.a('fitDataTag', 'flyLine'); mapGV.fitData(flyLine, false); } }); // ...省略

增加鼠標移到飛機相應位置進行名稱的提示、雙擊后显示飛機相應位置的信息面板並將視角聚焦到面板上、點擊飛機任意地方切換回飛機飛行模式等效果。 左側增加監控面板替代上面提到的雙擊相應位置這步操作直接聚焦到相應位置的信息面板上,這裏按鈕開啟了交互並添加了相應的交互邏輯,代碼如下:

button_JC.s({
    'interactive': true, 'onClick': function (event, data, view, point, width, height) { event.preventDefault(); let g3d = G.g3d, g3dDM = G.g3d.dm(); g3d.fireInteractorEvent({ kind: 'doubleClickData', data: g3dDM.getDataByTag(data.getTag()) }) } }); //...省略

 

天空渲染效果 既然是監控系統肯定是 24 小時無差別的監控,這就涉及到一個問題,我總不可能半夜的時候飛機也從瓦藍瓦藍的天空上飛過,這就很欠缺真實性了,所以要有一個天空從亮到暗再從暗到亮的過程,這個過程我暫定到 06:00-06:30 和19:00-19:30 這兩個時間段。   天空採用的是 
shape3d : ‘sphere’ 球形,包裹整個場景,然後使用 
reverse.flip 背拷貝 和 
blend 染色,之後天空就可以渲染成我想要的顏色,如果按照時間改變天空明暗只要改變染色值就可以了。   但是由於白天和晚上光照情況的不同,雲反射光的強度也不同,就導致了白天和晚上雲的差異,所以也要調整雲道和雲背景的貼圖的 
opacity 透明度,晚間更為透明度,代碼如下:

if ((hour > 6 && hour < 19) || (hour == 6 && minutes >= 30)) { timePane && timePane.a({ 'morning.visible': false, 'day.visible': true, 'dusk.visible': false, 'night.visible': false, 'day.opacity': 1 }) skyBox.s({ "shape3d.blend": 'rgb(127, 200, 240)', }) cloudBackground.s({ "back.opacity": 0.7, }) clouds.s({ "shape3d.opacity": 0.7, }) } else if ((hour < 6 || hour > 19) || (hour == 19 && minutes >= 30)) { //...省略 } else if (hour == 6 && minutes < 15 ) { //...省略 } else if (hour == 6 && minutes >= 15 && minutes < 30) { //...省略 } else if (hour == 19 && minutes < 15) { //...省略 } else if (hour == 19 && minutes >= 15 && minutes < 30) { //...省略 }

 

這裏我還增加了對右上角時間面板時間狀態圖標的支持,並增加了圖標切換時的漸隱漸顯效果,同時給時間面板狀態圖標位置增加了點擊切換到下一時間狀態的功能。   為了演示效果我增加了時間倍速按鈕,下圖是 500 倍時間流速下的變化情況:  
總結 身處大數據時代的我們,在網絡科技發展越來越快的環境下,迎來了 5G 的新征程和工業4.0的新變革,在信息數據採集傳輸和數據可視化系統的融合下,可以發掘出許多行業管控可視化系統的解決方案。而 HT 長久以來一直致力於多樣化行業系統可視化的搭建,涉獵的技術行業所累積的經驗,通過自主創新研發的技術產品,已經打造出許多行業上具有代表性意義的可視化管控系統,例如同樣有關於飛機的監控可視化系統: 無人機 3D 可視化系統 2019 我們也更新了數百個工業互聯網 2D/3D 可視化案例集,在這裏你能發現許多新奇的實例,也能發掘出不一樣的工業互聯網: https://mp.weixin.qq.com/s/ZbhB6LO2kBRPrRIfHlKGQA 同時,你也可以查看更多案例及效果: https://www.hightopo.com/demos/index.html 本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

當全世界的人們隨著網路時代而改變向上時您還停留在『網站美醜不重要』的舊有思維嗎?機會是留給努力改變現況的人們,別再浪費一分一秒可以接觸商機的寶貴時間!