信息泄漏時代,如何讓自己的密碼更安全?

密碼的重要性,相信大家都不言而喻。而密碼泄漏或信息泄漏,經常是層出不窮地出現,令人防不勝防。所以,一個強大而複雜的密碼是保證自己賬戶安全的第一步。

為了防止信息泄漏,我們可以做些什麼呢?

  • 密碼足夠複雜;
  • 每個平台密碼都不一樣,比如QQ,微信,郵箱等;
  • 定期更換密碼。

那怎樣的密碼才算是比較可靠的密碼?一般而言,一個密碼至少12位字符,包含数字,包含大小寫,包含特殊符號,不使用現有單詞,即是一個比較複雜的密碼。

那你自認為比較安全的密碼,是否真正的安全呢?這裏良許介紹兩個工具可以用來評估你的密碼的安全性—— cracklib 和 pwscore 。

cracklib介紹

1. cracklib 的安裝

cracklib 可以用來檢測你的密碼是否可靠,在大部分發行版里都可以直接安裝這個工具。

對於 Fedora 系的發行版,可以使用 dnf 命令安裝 cracklib:

$ sudo dnf install cracklib

對於 Debian/Ubuntu 系的發行版,可以使用 apt-get 命令安裝:

$ sudo apt install libcrack2

對於 Arch 系統的發行版,可以使用 pacman 命令安裝:

$ sudo pacman -S cracklib

對於 RHEL/CentOS 系的發行版,可以使用 yum 命令安裝:

$ sudo yum install cracklib

對於 openSUSE 系的發行版,可以使用 zypper 命令安裝:

$ sudo zypper install cracklib

2. cracklib 的使用

我們直接來看幾個實例。

如果你的密碼里包含了人名、地名,或者我們常用的單詞,那麼會被提示 it is based on a dictionary word :

$ echo "password" | cracklib-check
password: it is based on a dictionary word

Linux 下默認的密碼長度是 7 個字符,如果你的密碼長度小於 7 個字符,會被提示 it is WAY too short :

$ echo "123" | cracklib-check 
123: it is WAY too short

如果你的密碼比較強壯,則會提示 OK :

$ echo "ME$2w!@fgty6723" | cracklib-check
ME!@fgty6723: OK

pwscore 介紹

我們使用 cracklib 工具只能判斷一個密碼是否安全,但具體也不知道它有多安全。而 pwscore 工具就能告訴你,你的密碼強度可以打幾分。

1. pwscore 的安裝

同樣地,對於大部分 Linux 發行版,可以直接安裝 pwscore 工具。安裝過程與 cracklib 類似,只需將 cracklib 改成 pwscore 即可。這裏介紹 Debian/Ubuntu 系發行版的安裝,其餘的類似:

$ sudo apt install libpwquality

2. pwscore 的使用

同樣直接來看幾個實例。

與 cracklib 類似,如果你的密碼里包含了人名、地名,或者我們常用的單詞,那麼會被提示 it is based on a dictionary word ;如果密碼長度短於 7 個字符,會被提示 it is WAY too short 。

$ echo "password" | pwscore
Password quality check failed:
 The password fails the dictionary check - it is based on a dictionary word

$ echo "123" | pwscore
Password quality check failed:
 The password is shorter than 8 characters

如果你的密碼合乎規範,那麼它就會給你打相應的分數:

$ echo "ME!@fgty6723" | pwscore
90

小結

雖然黑客有一萬種竊取你的私人數據的方法,但一個強壯的密碼是你保護你敏感數據的第一步。網絡環境本身就不是 100% 安全,如果你再使用一個很容易玫破的密碼,那下一個艷照門可能很快就會再次出現……

公眾號:良許Linux

有收穫?希望老鐵們來個三連擊,給更多的人看到這篇文章

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

※產品缺大量曝光嗎?你需要的是一流包裝設計!

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

LG化學又傳工安意外 南韓工廠爆炸1死2傷

摘錄自2020年5月19日自由時報報導

南韓LG化學再傳工安意外,位在忠清南道瑞山市的催化劑工廠,在當地時間今(19)日下午2時20分(台灣時間下午1時20分)左右爆炸失火,造成1死2傷。

《韓聯社》報導,該化工廠的催化劑疑似在過高的壓力下爆炸而引發大火,火勢已在下午3時30分(台灣時間下午2時30分)被撲滅,據消防部門表示,沒有有害化學物質外洩。目前該設施已關閉,警方和消防部門將在清理現場後調查確切事故原因。

本月7日,LG化學在印度投資的一家化工廠發生重大事故,廠內兩座5000公噸級苯乙烯儲存槽因不明原因發生嚴重外洩,造成12人死亡,1000多人住院。

【其他文章推薦】

※新北市探針選用參考標準?

※如何知道自已的電腦cpu支不支持AVX指令集?

※如何正確使用飲水機?

※攻戰消費者第一視覺,包裝設計很重要!

※滑鼠墊適用各種文宣活動廣告曝光,專業客製服務

※封口機購物網-不怕你比價,就怕你買貴!

※高溫殺菌機最多可達多少溫度?

許多商店和批發商的低價自行車都賣光了。現在美國的自行車嚴重缺貨

許多商店和批發商的低價自行車都賣光了。現在美國的自行車嚴重缺貨,受疫情中斷的全球供應鏈加緊趕工,以供應大量增加的需求。

紐約市4月宣布將暫時開放100英里路段給行人和自行車騎士,官員說,這可能變成永久政策。奧克蘭市計畫在疫情期間關閉10%街道,禁止汽車通行;西雅圖也將永久封閉20英里路段。

【其他文章推薦】

※無塵擦拭布各大品牌廠商販售比價網!

※如何正確使用飲水機?

※如何知道自已的電腦cpu支不支持AVX指令集?

※掌握產品行銷策略,帶你認識商品包裝設計基本要素

※精密CNC 自動車床設備介紹

※空壓機這裡買最划算!

停止依賴中國稀土 美國防部提案擴大投資上限

摘錄自2020年5月19日自由時報報導

美國國防部已對國會提出一項提案,擴大對稀土的投資上限,以停止對中國的依賴程度,這些稀土可以用來製造飛彈和彈藥、極音速武器,及相關電子產品。如果美國可以重新生產稀土,中國打「稀土牌」的威脅程度將大幅降低。

根據《國防新聞》報導,美國國防部希望提高《國防生產法》的支出上限,在開採稀土上提升至最高17.5億美元(約新台幣523億),在微電子晶片上增至3.5億美元(約新台幣104億),當涉及到極音速武器時,將會沒有上限。據悉,此提案已於本月初提出,已納入國會正在起草的年度國防政策法案。

美國防部副部長洛德(Ellen Lord)去年8月曾表示,國防部正與澳洲進行談判,要求其為美軍提供稀土。澳洲Lynas公司擁有稀土礦,同時在馬來西亞也有精煉廠,可能是此計劃的核心。

【其他文章推薦】

※客製專屬滑鼠墊、可愛造型L夾、L型資料夾、透明證件套、手提袋,專業印刷設計廠商!  

※示波器鮮為人知的使用技巧?

※掌握產品行銷策略,帶你認識商品包裝設計基本要素

※買不起高檔茶葉,精緻包裝茶葉罐,也能撐場面!

※貨梯使用安全與保養

※高效率洗滌塔活性碳設備有哪些?

※專業模具開發-五金製品代工製作廠

SSH原理常見應用升級及端口轉發

SSH介紹

SSH是Secure Shell Protocol的簡寫,由IETF網絡工作小組(Network working Group)指定;在進行數據傳輸之前,SSH先對聯機數據包通過加密技術進行加密處理,加密后在進行數據傳輸。確保了傳遞的數據安全.

SSH是專為遠程登錄會話和其他網絡服務提供的安全性協議。利用SSH協議可以有效的放置遠程管理過程中的信息泄露問題,在當前的生產環境運維工作中,絕大多數企業普遍採用SSH協議服務來代替傳統的不安全的遠程聯機服務軟件,如telnet(23端口,非加密)

在默認狀態下,SSH服務主要提供了兩個服務功能,一個是提供類似Telnet遠程聯機服務器的服務,即上面提到的SSH服務;另一個是類似FTP服務的sftp-server,藉助SSH協議來傳輸數據的,提供更安全的SFTP服務(vsftp,proftp)

ssh 客戶端(ssh命令)還包含一個遠程安全拷貝命令scp,也是通過ssh協議工作.

小結

# 1、SSH是安全的加密協議,用於遠程連接linux服務器
# 2、SSH默認端口是22,安全協議版本SSH2,除了2之外還有SSH1(漏洞)
# 3、SSH服務端主要包含兩個服務協議SSH遠程連接,SFTP服務
# 4、Linux SSH客戶端包含ssh遠程連接命令,以及遠程拷貝scp命令

SSH結構

# SSH服務由服務端軟件OpenSSH (openssl)
# 客戶端(常見的有SSH(linux),SecureCRT,Putty,Xshell)組成

# SSH服務默認使用22端口提供服務,它有兩個不兼容的SSH協議版本分別是1.x和2.x

rpm -qa openssh
openssh-6.6.1p1-31.el7.x86_64		# 遠程連接安裝包

rpm -qa openssl
openssl-1.0.2k-19.el7.x86_64		# 加密安裝包

OpenSSH同時支持SSH 1.x和2.x 用SSH 2.x的客戶端程序不能鏈接到SSH1.x的服務程序上

SSH服務是一個守護進程(daemon),他在後台運行並響應來自客戶端的連接請求,SSH服務端的進程名為sshd,負責實時監聽遠程SSH客戶端的連接請求,並進行處理,一般包括公共密鑰認證、密鑰交換、對稱密鑰加密和非安全連接等。

SSH客戶端包含ssh以及像scp(遠程拷貝)slogin(遠程登錄)sftp(安全FTP文件傳輸)等應用程序

SSH的工作機制大致是本地的ssh客戶端發送一個連接請求到遠程的ssh服務器,服務器檢查連接的客戶端發送的數據包和ip地址,如果確認合法,就會發送密鑰給SSH的客戶端,此時,客戶端本地再將密鑰發回給服務端,自己建立連接。SSH1.x和SSH2.x在連接協議上有一些安全方面的差異

SSH加密技術

SSH加密技術是將人類可以看得懂的數據,通過一定的特殊的程序算法,把這些數據變成雜亂的無意義的信息,然後,通過網絡進行傳輸,二擋到了目的地后,在通過對應的解密算法,把傳過來的加密的數據信息解密成加密前的可讀取的正常數據。因此,當數據在互聯網上傳輸時即使被有心的黑客監聽竊取了,也很難獲取到真正需要的數據

網絡上的數據包加密技術一般是通過所謂的一對公鑰和私鑰(Public key and Pivate key)組合撐的密鑰對進行加密與解密操作。

SSH 1.x

每一台SSH服務器主機都可以使用RSA加密方式來產生一個1024-bit的RSA Key 這個RSA的加密方式就是用來產生公鑰和私鑰的算法之一。

當服務啟動時,就會產生一個768 bit的臨時公鑰存放在Server中

grep ServerKey /etc/ssh/sshd_config 
#ServerKeyBits 1024
SSH 2.x

在SSH 1.x的聯機過程中,當Server接收Clinet端的Private Key后,就不再針對該次聯機的Key pair進行檢驗。若此時有而已黑客對該聯機key pair插入而已的程序代碼時,由於服務端你不會在檢驗聯機的正確性,因此可能會接收該程序代碼,從而導致系統被黑.

為了改正這個缺點,SSH version2多加了一個確認聯機正確性的Diffie-Hellman機制

在每次數據傳輸中,Server都會以該機制檢查數據的來源是否正確,這樣,可以避免聯機過程中被插入而已程序代碼的問題

另外,SSH2同時支持RSA和DSA密鑰,但是SSH1僅支持RSA密鑰

由於SSH1協議本身存在較大問題,建議使用SSH2的聯機模式

當Client端SSH聯機請求傳送過來時,Server就會將這個768-bit的公鑰傳給Client端

此時Client會將此公鑰與先前存儲的公鑰進行對比,看是否一致,判斷標準是Client端聯機用戶目錄下~/.ssh/known_hosts文件的內容(linux-客戶端)

不加用戶默認是root 不加-p 指定端口 默認是22`

ssh -p22222 root@39.108.140.0
The authenticity of host '39.108.140.0 (39.108.140.0)' can't be established.
ECDSA key fingerprint is 17:33:ef:9b:05:b3:69:d3:20:48:49:e1:28:9b:7c:c8.
Are you sure you want to continue connecting (yes/no)? 

# 連接密碼文件存放路徑
cat /root/.ssh/known_hosts 
121.36.43.223 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDgQ7H6KDIPTzOklwMSOxgFI0Xc3rgvwPnCLIuXIuzaCfYQBouM6owCArpj2CXEyk40lSn96ktW1vETbP1JmjEY=

# 第一次SH連接的時候,本地會產生一個密鑰文件~/.ssh/known_hosts
如何防止SSH登錄入侵
# 1、用密鑰登錄,不用密碼登錄
# 2、牤牛陣法:解決SSH安全問題
# 3、防火牆封閉SSH,指定源限制(局域網,信任公網)
# 4、開啟SSH只監聽本地內網IP(ListenAddress 10.0.0.8)
# 5、盡量不給服務器外網IP

SSH客戶端附帶的scp命令

scp的基本語法使用:scp -sercure copy (remote file copy program)

推push

scp -P22 -rp /root/test.txt root@39.108.140.0:/root/

拉pull

scp -p22 -rp root@39.108.140.0:/root/test.txt ./

# -P 指定端口,默認22,可忽略
# -p 表示拷貝前後保持文件或目錄屬性
# -r 遞歸,表示拷貝目錄
# -l 限制速度

# 小結
# 1、scp是加密的遠程拷貝,而cp僅為本地拷貝
# 2、可以把數據從一台機器推送到另一台機器,也可以從其他服務器把數據拉回到本地執行命令的服務器
# 3、每次都是全量完成拷貝,因此效率不高,適合第一次拷貝用,如果需要增量拷貝,用rsync
ssh服務附帶的sftp功能服務
# 1. rz,sz(lrzsz)
# 2. winscp WinSCP-v4.0.5 基於SSH,sftp
# 3. SFX(xshell) 4) SFTP 基於SSH加密傳輸
# 4. samba,http,ftp,nfs
# FTP工具:vsftp、proftpd、SFTP

# linux sftp客戶端登錄sftp服務方法
# 登錄FTP的方法就是
sftp -oPort=22 root@39.108.140.0:
sftp> put test.txt
Uploading test.txt to /root/test.txt
test.txt                                          100%    0     0.0KB/s   00:00                                   
sftp> ls test.txt 
test.txt

SSH服務認證類型介紹

基於口令安全認證

基於口令的安全驗證的方式就是大家現在一直在用的,只要知道服務器的SSH端口號和口令,應服務器的IP及開放的端口,默認都為22,就可以通過ssh客戶端登錄到主機,此時聯機過程中所有傳輸都是加密的

基於密鑰的安全驗證

基於密鑰的安全驗證方式是指,需要依靠密鑰,也就是必須事先建立一對密鑰,然後把公用密鑰(Publickey)放在需要訪問的目標服務器上,另外,個還需要把私有密鑰(Private key)放到SSH客戶端或對應的客戶端服務器上

此時,如果要想連接到這個帶有公用密鑰的SSH服務器,客戶端SSH軟件或者客戶端端服務就會想SSH服務端發出請求,請求用聯機用戶密鑰進行安全連接。SSH服務會在收到請求之後,會現在改SSH服務器上連接的用戶的加密路下 放上去的對應用戶密鑰,然後把它和連接的SSH客戶端發來進行密鑰,如果兩個密鑰一直SSH服務就會用公用密鑰加密“質詢”(challenge)並把它發送給SSH客戶端

更改ssh 默認登錄配置

修改SSH服務的運行參數,是通過修改配置文件/etc/ssh/sshd_config實現的

一般來說SSH服務使用默認的配置已經夠很好的工作,如果對安全要求不高,僅僅提供SSH服務的情況不需要修改任何配置

sshd_config配置文件說明:

優化SSH配置文件選項
cp /etc/ssh/sshd_config{,.bak}
vim /etc/ssh/sshd_config
Port 52113              # ssh連接端口默認為22,修改端口號可以提高級別
PermitRootLogin no      # 禁止root遠程登錄
PermitEmptyPasswords no # 禁止空密碼的用戶登錄
UseDNS no               # 不使用DNS進行解析
GSSAPIAuthentication no # 會導致SSH連接慢

# ssh遠程連接服務滿解決方法
sed -ri '13 iPort 52113\nPermitRootLogin no\nPermitEmptyPasswords no\nUseDNS no\nGSSAPIAuthentication no' /etc/ssh/sshd_config

SSH優化

優化sshd_config
sed -i '13 iPort 52113\nPermitRootLogin no   \n   禁止root登錄
PermitEmptyPasswords no \n      #        禁止使用密碼
UseDNS no\n                     # 禁用DNS
GSSAPIAuthentication no'        #        禁用GSSAPI
sshd_config
檢查hosts解析
cat >>/etc/hosts <<EOF
39.108.140.0 blog
149.129.38.117 blog2
121.36.43.223 huawei 
49.233.69.195 tenxun 
116.196.83.113 jd 
EOF

useradd oldboy
echo "123456"|passwd --stdin youmen
su – youmen
ssh-keygen -t dsa   //非交互式創建密鑰  

#ssh-keygen是生產密鑰的工具 -t參數是指定密鑰的類型,這裡是建立dsa類型密鑰
#也可以使用ssh-keygen -t rsa來建立rsa類型密鑰

#RSA與DSA加密算法的區別
#RSA:是一種加密算法(PS:RSA也可以進行数字簽名的)它的簡寫的來由是RonRivest、Adi Shamir和LeonAdleman 這三個姓氏加在一起就是RSA

#DSA就是数字簽名算法的英文全稱的簡寫,即Digital Sigenature Algorithm=DSA

# RSA既可以進行加密,也可以進行数字簽名實現認證,而DSA只能用於数字簽名
分發密鑰
yum -y install sshpass
ssh-keygen -t rsa -P '' -f ~/.ssh/id_dsa &>/dev/null
sshpass -p youmen ssh -o StrictHostKeyChecking=no  root@192.168.43.159


# 一鍵生成密鑰對
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa >/dev/null 2>&1

ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.43.159
# -i 代表要發送的文件

# ssh-copy-id 只能發公鑰,不能發私鑰

# 1 免密碼登錄是單向的,方向從私鑰(鑰匙)==》公鑰(鎖)
# 2 SSH免密碼登錄基於用戶的,最好不要跨不同的用戶
# 3 ssh連接慢的問題解決
ssh批量管理步驟
# 1、ssh優化和hosts解析
# 2、創建用戶
# 3、生成密鑰對
# 4、分發公鑰到所有服務器 ssh-copy-id
# 5、測試 遠程連接ssh 遠程執行命令ssh ifconfig
# 遠程拷貝文件scp rsync-e隧道模式

ssh常見操作

將本地hosts發送指定IP

1. sudo提權實現沒有權限用戶拷貝

echo“youmenALL= NOPASSWD:/usr/bin/rsync ”>>/etc/sudoers

visudo -c 

scp -P52113 hosts oldboy@192.168.43.159:~	# 最好發送到家目錄下,直接發送到/下是沒有權限

ssh -p22 -t youmen@192.168.43.159 sudo rsync ~/hosts /etc/hosts
# 需要授權sudo權限

2. 使用suid實現沒有權限用戶拷貝

chmod u+s `which rsync`
scp -P22 hosts oldboy@192.168.43.159:~
ssh -p22 youmen@192.168.43.159 rsync ~/hosts  /etc/hosts

3. 使用root進行操作

# rsync使用
rsync -avz hosts -e ‘ssh -p 22’youmen@192.168.43.159:~
# 可以增量備份
查看hosts主機系統版本
 cat view.sh 
#!/bin/sh
for n in blog2 tenxun jd huawei 
do
  echo -n "====$n===="	
  ssh -p 22 $n $1		
done
[root@nginx_test ~]# sh view.sh "cat /etc/redhat-release"
====blog2====CentOS Linux release 7.3.1611 (Core) 
====tenxun====CentOS Linux release 7.6.1810 (Core) 
====jd====CentOS Linux release 7.6.1810 (Core) 
====huawei====CentOS Linux release 7.4.1708 (Core) 
分發文件
cat file.sh 
#!/bin/sh
. /etc/init.d/functions
if [ $# -ne 1 ];then 
    echo "USAGE:/bin/sh $0 FILENAME"	$
    exit 1    
fi
for n in blog2 tenxun jd huawei 
do
  echo -n "====$n===="	
  scp -P22 $1  $n: &>/dev/null
  if [ $? -eq 0 ];then
      action "dis $1 to $n" /bin/true
else
      action "$n" /bin/false
fi
done

sh file.sh /etc/hosts
====blog2====dis /etc/hosts to blog2                       [  OK  ]
====tenxun====dis /etc/hosts to tenxun                     [  OK  ]
====jd====dis /etc/hosts to jd                             [  OK  ]
====huawei====dis /etc/hosts to huawei                     [  OK  ]

SSH端口轉發簡介

SSH會自動加密和解密所有SSH客戶端與服務端之間的網絡數據。但是,SSH還能夠將其他TCP端口的網絡數據通SSH鏈接來轉發,並且自動提供了相應的加密及解密服務。這一過程也被叫做”隧道“(tunneling),這是因為SSH為其他TCP鏈接提供了一個安全的通道來進行傳輸而得名。例如,Telnet ,SMTP ,LDAP這些TCP應用均能夠從中得益,避免了用戶名,密碼以及隱私信息的明文傳輸。而與此同時,如果工作環境許中的防火牆限制了一些網絡端口的使用,但是允許SSH的連接,也能夠將通過將TCP用端口轉發來使用SSH進行通訊。

SSH端口轉發兩大功能
# 1. 加密SSH Client端至SSH Server端之間的通訊數據。
# 2. 突破防火牆的簡直完成一些之前無法建立的TCP連接。

本地轉發

命令 -L localport:remotehost:remotehostport sshserver

說明

localport      #  本機開啟的端口號
remotehost      # 最終連接機器的IP地址
remotehostport     #  轉發機器的端口號
sshserver      #  轉發機器的IP地址

# -L 本機端口
# -f 後台啟用,可以在本機直接執行命令,無需另開新終端
# -N 不打開遠程shell,處於等待狀態,不跳到遠程主機,還在主機上,只是搭好了隧道,橋搭好,不ssh上去
# -g 啟用網關功能
# -R 服務端口

# 舉例:
ssh –L 9527:telnetsrv:23 -N sshsrv
telnet 127.0.0.1 9527
# 當訪問本機的9527的端口時,被加密後轉發到sshsrv的ssh服務,再解密被轉發到telnetsrv:23
data < >localhost:9527 < > localhost:XXXXX < > sshsrv:22 < > sshrv:yyyyy < > telnetsrv:23
環境背景

背景:企業內部C服務器只允許telnet連接(23端口)訪問,不允許外部直接訪問,B服務器是一個ssh服務器;有一個用戶需要從外部連接到企業內部的C服務器。

前提:防火牆允許22端口進來(或者企業內部有一個堡壘機,ssh -t通過堡壘機進去)。

原理: 數據一旦telnet以後,數據會發送到本機9527端口,再在本機開一個隨機端口,充當ssh客戶端,再把數據流量發送到22端口的ssh服務端,收到數據以後,解密數據,臨時開一個隨機端口充當客戶端,再把流量發送到23端口telnet服務端

機器: blogA用戶,huawei模擬B機器,tenxun模擬C機器

節點名 IP 軟件版本 硬件 網絡 說明
CentOS7-A 39.108.140.0 1C2G 公有雲 阿里雲
CentOS6-B 121.36.43.223 1C2G 公有雲 華為雲
CentOS6-C 49.233.69.195 1C2G 公有雲 騰訊雲
# ssh協議裏面封裝了telnet,一旦A連接了B主機,立即使用telnet連接C主機,此過程可以突破防火牆的限制
# 實驗
#   A->C    訪問被限制
#    A-B->C  使用B主機作為跳板突破訪問限制
配置步驟

C機器通過iptables拒絕A機器登錄

[root@C ~]# iptables -A INPUT -s 39.108.140.0 -j REJECT
[root@C ~]# yum -y install telnet-server xinetd
[root@C ~]# systemctl start telnet.socket
[root@C ~]# systemctl start xinetd
[root@C ~]# ss -tnl |grep 23
LISTEN     0      128       [::]:23                    [::]:*   

# 此時我們A機器是直接連接不上C機器的
[root@A ~]# ssh 49.233.69.195
ssh: connect to host 49.233.69.195 port 22: Connection refused

# 開啟端口轉發(telnet隧道)
[root@A ~]# ssh -L 10000:49.233.69.195:23 -Nf 121.36.43.223
# 通過本地9527端口訪問centos6-1服務器IP地址使用telnet協議23端口,跳板機ip地址

# 隧道已經搭建好了,此時A主機可以通過telnet訪問C主機
telnet 127.0.0.1 10000
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.

Kernel 3.10.0-1062.9.1.el7.x86_64 on an x86_64
c login: youmen
Password: 
Last login: Fri Jun 12 22:32:04 from centos-b
[root@C ~]$

# 如何需要刪除這個連接使用killall ssh即可
killall ssh   # 刪除搭建的橋
telnet 127.0.0.1 10000
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused

遠程轉發

遠程轉發機制

# -R sshserverport:remotehost:remotehostportsshserver

# 舉例
ssh–R 9527:telnetsrv:23 –N sshsrv
# 讓sshsrv偵聽9527端口的訪問,如有訪問,就加密后通過ssh服務轉發請求到本機ssh客戶端,再由本機解密後轉發到telnetsrv:23
Data < > sshsrv:9527 < > sshsrv:22 < > localhost:XXXXX < > localhost:YYYYY< >telnetsrv:23

# 需求:
# 在A(Centos7)上開啟smtp服務(postfix),B(Centos6)做跳板,C(Centos6-1)客戶端給Centos7發送郵件

# 流程解釋
C-x->A    (拒絕訪問)
C-B->A      (通過遠程代理,接受訪問)  

環境依然是上面三台機器,只是C服務器換成116.196.83.113 (JD)這台服務器

配置步驟
[root@A ~]# vim /etc/postfix/main.cf 
# inet_interfaces = localhost  # 註釋此行,不讓接口直接綁定在127.0.0.1上
[root@A ~]# systemctl restart postfix
[root@A ~]# ss -tnl |grep 25
LISTEN     0      100          *:25                       *:*                  
LISTEN     0      100         :::25                      :::*  

[root@A ~]# yum -y install telnet-server
[root@A ~]# systemctl start telnet.socket

# 如果B上面有一些影響的防火牆規則就將它刪掉
[root@B ~]# iptables -nL --line-number
[root@B ~]# iptables -D INPUT 1

# 測試下C能不能telnet 25端口連接A
[root@C ~]# 39.108.140.0 25
Trying 39.108.140.0...
Connected to 39.108.140.0.
Escape character is '^]'.
220 nginx_test.localdomain ESMTP Postfix

# 設置防火牆策略,使A不接受C的一切請求
[root@A ~]# iptables -A INPUT -s 39.108.140.0 -j REJECT
[root@C ~]# telnet 39.108.140.0 25
Trying 39.108.140.0...
telnet: connect to address 39.108.140.0: Connection refused

# 使用B遠程轉發,發送郵件到
[root@B ~]# ssh-copy-id root@116.196.83.113:
# 使用B遠程轉發,發送郵件到A,最好免密,否則需要手動口令驗證
[root@B ~]#  ssh -R 50000:39.108.140.0:25 -fN 121.36.43.223

# 此時可以到C跳板機看到已經有端口在監聽了
[root@C ~]# ss -tnl |grep 50000
LISTEN     0      128    127.0.0.1:50000                    *:*                

[root@C ~]# telnet 127.0.0.1 5000
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
[root@zabbix ~]# telnet 127.0.0.1 50000
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
220 nginx_test.localdomain ESMTP Postfix
mail from:youmen@163.com      
250 2.1.0 Ok

openssh升級

下載地址

http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/

具體升級步驟
# 記錄sshd.pid路徑
find / -name sshd.pid

# 查看openssh現有版本
ssh -V

# 使用rpm刪除現有的openssh
rpm -e --nodeps $(rpm -qa | grep openssh)

# 刪除舊的配置文件
rm -rf /etc/ssh/*

# 安裝openssl-devel
yum -y install openssl-devel

# 下載tar.gz包,配置編譯,安裝
wget http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-8.0p1.tar.gz

# 編譯並安裝
tar xvf openssh-8.0p1.tar.gz 
cd openssh-8.0p1
./configure --prefix=/usr/ --sysconfdir=/etc/ssh/ --with-ssl-dir=/etc/ssl --with-md5-passwords --mandir=/usr/share/man/
make && make install

# 設置ssh服務開機自啟動
# 複製啟動文件至/etc/init.d/
cp -a contrib/redhat/sshd.init /etc/init.d/sshd
     
# 編輯/etc/init.d/sshd文件, 將PID_FILE改為之前記下的sshd.pid路徑
    sed -i "s/PID_FILE=\/var\/run\/sshd.pid/PID_FILE=\/run\/sshd.pid/" /etc/init.d/sshd
     
# 設置開機啟動sshd
    chkconfig sshd on
    chkconfig --list sshd
    
    
# 編輯/etc/ssh/sshd_config, 設置一些常用參數
sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/" /etc/ssh/sshd_config
sed -i "s/#PubkeyAuthentication yes/PubkeyAuthentication yes/" /etc/ssh/sshd_config
sed -i "s/#PasswordAuthentication yes/PasswordAuthentication yes/" /etc/ssh/sshd_config
sed -i "s/#AllowTcpForwarding yes/AllowTcpForwarding yes/" /etc/ssh/sshd_config
sed -i "s/#X11Forwarding no/X11Forwarding yes/" /etc/ssh/sshd_config
sed -i "s/#PidFile \/var\/run\/sshd.pid/PidFile \/run\/sshd.pid/" /etc/ssh/sshd_config

# 加入系統服務
cat > /usr/lib/systemd/system/sshd.service  << EOF
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
#After=network.target sshd-keygen.service
#Wants=sshd-keygen.service
After=network.target
[Service]
ExecStart=/usr/sbin/sshd
[Install]
WantedBy=multi-user.target
EOF

# 啟用sshd服務
systemctl enable sshd
# 重啟服務
systemctl restart sshd
# 查看服務狀態
systemctl status sshd

# 驗證
ssh -V
OpenSSH_8.0p1, OpenSSL 1.0.2k-fips  26 Jan 2017

SSH設置登錄歡迎信息

到/etc/motd裏面編寫內容,看個人愛好

[root@nginx_test ~]# cat /etc/motd 
  /\/\
  (_人|人_)
   /‥\
  ミ(_Y_)ミ
   > <
  (/ \)
  _(   )_
 (_>―<_)

# 關閉當前會話再登錄
  /\/\
  (_人|人_)
   /‥\
  ミ(_Y_)ミ
   > <
  (/ \)
  _(   )_
 (_>―<_)
[root@nginx_test ~]#
小熊圖案
┴┬┴┬/ ̄\_/ ̄\   
┬┴┬┴▏  ▏▔▔▔▔\   
┴┬┴/\ /      ﹨   
┬┴∕       /   )   
┴┬▏        ●  ▏   
┬┴▏           ▔█    
┴◢██◣     \___/   
┬█████◣       /     
┴█████████████◣   
◢██████████████▆▄   
█◤◢██◣◥█████████◤\   
◥◢████ ████████◤   \   
┴█████ ██████◤      ﹨   
┬│   │█████◤        ▏   
┴│   │              ▏   
┬ ∕    ∕    /▔▔▔\     ∕   
┴/___/﹨   ∕     ﹨  /\   
┬┴┬┴┬┴\    \      ﹨/   ﹨   
┴┬┴┬┴┬┴ \___\     ﹨/▔\﹨ ▔\   
▲△▲▲╓╥╥╥╥╥╥╥╥\   ∕  /▔﹨/▔﹨   
   **╠╬╬╬╬╬╬╬╬*﹨  /  //

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

【其他文章推薦】

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

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

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

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

※產品缺大量曝光嗎?你需要的是一流包裝設計!

redis 主從複製

redis 主從複製

master 節點提供數據,也就是寫。slave 節點負責讀。

不是說master 分支不能讀數據,也能只是我們希望將讀寫進行分離。

slave 是不能寫數據的,只能處理讀請求

主從實現

客戶端 127.0.0.1:6379 服務器 212.64.89.173:6379

方式一

客戶端發送請求同步命令

slaveof masterip masterport

slaveof 212.64.89.173 6379

方式二

客戶端啟動服務器參數

redis-server --slaveof masterip masterport

redis-server --slaveof 212.64.89.173 6379

方式三

在客戶端的配置文件中寫入 slaveof 信息

redis.conf

slaveof 212.64.89.173 6379

注意 斷開主從鏈接方式: 客戶端執行 slaveof no one

設置鏈接密碼

server 端

服務啟動後設置

config set requierpass <password>

配置文件添加密碼

# redis.conf
requirepass <password>

client 端

命令設置密碼

auth <password>

配置文件設置密碼

masterauth <password>

啟動客戶端設置密碼

redis-cli -a <password>

建立連接

建立鏈接的過程就是希望 master 和 slave 都保有對方的 IP 和 Port。

數據同步

數據的同步分兩部分,全量同步和增量同步,在增量同步結束后,master 應當保存Slave 同步數據的位置。

複製(積壓)緩衝區

它有兩部分組成 偏移量 + 字節值

結構

創建

1 當啟動AOF 時就會創建 複製積壓緩衝區

2 當被選為 master 節點,必須創建積壓緩衝區

作用

保存所有的對數據修改或數據庫修改的指令,查詢指令不會被記錄。

數據源

所有的進入master 的對數據修改或數據庫修改的指令都會被填充到積壓緩衝區中。

偏移量

1 Master 和 Slave 都會記錄 offset 值, 每次複製都會對比offset 是否一致。如果一致,Master直接從 offset 處開始傳緩衝區數據,如果不一致,那麼Master將遵循 Slave 的offset 來傳。當然會保證命令是完整的。

2 Master 保存有多個 offset 而 Slave 僅保存自己的。

3 Master發送一次,記錄一次, Slave 接受一次記錄一次。

關於Master注意

1如果master 數據量過大,應該避免業務高峰期進行數據同步。避免造成 master 阻塞

2 數據緩衝區滿, 此時將會丟棄最早的記錄(FIFO),如果全量複製的時間開銷過大,則可能在開增量複製時候已經存在數據丟失,這會導致Master 和 Slave 數據不一致,為了保證一致性,必須開始新一輪的全量複製,完成后緩衝區又被填滿並存在丟棄,則會讓Slave進入死循環。

因此數據緩衝區要設置的大小合適(依具體情況而定)。

repl-backlog-size 1mb   # 默認的大小為 1MB

3 master 單機內存不應該佔用主機內存過多。一般的 50 ~ 70% 預留下 30% ~ 50%來進行bgsave 、 創建複製緩衝區、執行其他業務等。

關於Slave注意

1 為避免slave進行全量複製、部分複製時服務器響應阻塞或數據不同步,建議關閉此期間的對外服務。

slave-server-stale-data yes|no

2 數據同步階段,master 發送給 slave 信息可以理解 master 是 slave 的一個客戶端,主動向slave發送命令。

3 多個slave同時對master請求數據同步,master發送的RDB文件增多,會對帶寬造成巨大衝擊,如果master寬帶不足,因此數據同步需要根據業務需求,適量錯峰。

4 slave過多時,應該對拓撲結構進行調整,由一主多從結構變為樹狀結構,中間結點即是master,也是slave。但是使用樹狀結構時,因為層級越深,數據同步時延越大,因此將強一致性的數據放在頂層節點,一致性稍弱的數據放在靠底層的節點。

命令傳播

當master數據庫狀態被修改后,導致主從服務器數據庫狀態不一致,此時需要讓主從數據同步到一致的狀態,同步的動作成為命令傳播
master將接受到的數據變更命令發送給slave,slave接受命令后執行命令。

網絡閃斷閃連 忽略
短時間網絡中斷 部分複製
長時間網絡中斷 全量複製

服務器運行ID(runid)

每台服務器每次運行都會產生的身份識別碼,同一個服務器多次運行產生的runid是不一樣的。

形式:runid 由 40 個字符組成 一般是16進制的字符串

info server
run_id:409b6e9ea2e5c32958de8f365711598c98489f13

心跳機制

master

指令 PING

周期 repl-ping-slave-period 默認是 10s

作用 判斷 slave 是否在線

查詢 INFO replication 獲取最後一次 slave 連接時間間隔 lag = 0 / 1 屬於正常

slave

指令 REPLCONF{offset}

周期: 1s

作用1: 彙報自己的複製偏移量 獲取最新的數據變更指令

作用2: 判斷 master 是否存活

心跳注意事項

當 salve多數掉線 或者網絡延時過高時,master 會拒絕所有的同步信息。

min-slaves-to-write 2   # 最小的 slave 數量

min-slaves-max-lag 8  # 最長的

當 slave 的數量小於2 ,或者所有的時延都大於等於 8 時,會強 關閉 master 的血功能來停止數據同步。

Slave 的數量和延時由REPLCONF{offset} 命令確認。

完整的主從複製流程

讀寫分離

在redis主從架構中,Master節點負責處理寫請求,Slave節點只處理讀請求。對於寫請求少,讀請求多的場景,例如電商詳情頁,通過這種讀寫分離的操作可以大幅提高併發量,通過增加redis從節點的數量可以使得redis的QPS達到10W+。

負載均衡

基於主從結構,配合讀寫分離,由slave分擔master負載,並根據需求的變化,改變slave的數量,通過多個從節點分擔數據讀取負載,大大提高Redis服務器併發量與數據吞吐量

故障恢復

當master出現問題時,由slave提供服務,實現快速的故障恢復

數據冗餘

實現數據熱備份,時持久化之外的一種數據冗餘方式

高可用基石

基於主從複製,構建哨兵模式與集群,實現redis 的高可用方案。

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

【其他文章推薦】

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

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

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

※超省錢租車方案

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

※產品缺大量曝光嗎?你需要的是一流包裝設計!

【JAVA進階架構師指南】之五:JVM性能調優

前言

  首先給大家說聲對不起,最近屬實太忙了,白天上班,晚上加班,回家還要收拾家裡,基本每天做完所有事兒都是凌晨一兩點了,沒有精力再搞其他的了.
  好了,進入正題,讓我們來聊聊JVM篇最後一個章節—-JVM性能調優.童鞋們隨便打開一個大廠的招聘崗位JD,應該都會有JVM調優相關的描述,其實招聘方不一定要求候選人真的對JVM調優有實際調優經驗,但是至少得有思路,知道應該怎樣進行JVM層面的性能調優,說實話,知道如何進行JVM層面的性能調優的人,在面試中確實是有加分的.
  筆者在公司擔任面試官的時候,經常會看到候選人簡歷描述有JVM性能調優經驗,每當這個時候我都會問候選人一個問題,你是如何進行JVM性能調優的,很多童鞋的回答就是:噢,就是調整一下初始堆大小,新生代大小.這明顯不是筆者想要的答案,因為這根本就不叫JVM性能調優.童鞋們對號入座一下,對JVM調優僅僅是我上述說的那樣的,趕緊改一下簡歷,不要說自己會JVM性能調優.說實話,對JVM進行性能調優是對架構師的要求,甚至我敢說很多架構師都不一定有實際的JVM性能調優經驗.話不多說,讓我們進入正題,我們將從以下幾點來講解如何進行性能調優:

  • JVM性能調優的前提
  • JVM性能調優的預備知識
  • STW現象–Stop-The-World
  • 垃圾回收器的種類
  • 性能調優的目的
  • 如何進行性能調優

JVM性能調優的前提

  所有有經驗的架構師一定會有一個共識,JVM層面的性能調優一定是作為最後的調優手段,在此之前,一定要確保系統其它方面都已經做到了極致,無法再進行調優了,在這個前提下,才會考慮JVM性能調優.這裏的其他方面包括從前端到架構到代碼層面,我舉一些例子
從瀏覽器/APP角度可進行的優化有:

  • 減少HTTP請求次數.
  • 使用客戶端緩存.
  • 瀏覽器啟用壓縮
  • 使用CDN加速
  • 動態資源和靜態資源分離

從系統層面可進行的優化有:

  • 啟用緩存,比如redis緩存數據
  • 使用集群
  • 異步處理,比如引入消息隊列
  • 對代碼的優化

  以上列出的每一點,都能單獨拎出來講很久,但是博文篇幅問題,就不細說了,有興趣的童鞋可以自行下去了解,我們只着重說一下代碼優化,相信大家都知道,業界比較公認的編碼規範是阿里巴巴發布的<java開發手冊>,裏面的內容都是阿里集團多年來血的教訓積累的精華,阿里集團內部有一個組織專門負責手冊的編寫和推廣,並且在不斷進行優化,最新版發布到泰山版了(我看的時候還是華山版,哈哈).如果有童鞋還不知道的,我建議去下載下來看一看.另外阿里雲上有<java開發手冊>的考試,如果通過了這個考試,說明你的編碼規範還是不錯的,有興趣的童鞋可以去試一下.
  除此之外,童鞋們還應該了解JVM本身為我們悄悄做的各種優化,其中最重要的是JIT編譯器的優化.我舉幾個例子,比如:方法內聯,逃逸分析等.默認情況下,這些都是開啟的,如果不開啟這些功能,JVM性能會下降50%以上.除此之外,還有一些比如:棧上分配,TLAB等優化.這些內容由於平時我們開發中不會用到,是JVM在背後悄悄為我們做了優化,因此可能很多童鞋都不知道,但是如果想成為一個合格的架構師,這些內容都是必須要知道的,畢竟架構師的知識廣度和深度決定了架構師的高度.
  除此之外,性能調優一定是基於性能測試的,空口說進行性能調優的都是耍流氓,只有在經過了實際的性能測試后,我們才知道系統的瓶頸在哪裡,才知道那些方面需要進行調優,如何進行調優.常用的性能測試指標有TPS/QPS/吞吐量.並且默認所有的接口訪問都遵循二八原則(接口每天80%的訪問量集中在20%的時間內).

JVM性能調優的預備知識

  在進行JVM性能調優之前,我們還得了解JVM,比如我前面的幾篇有關JVM的博文,都是需要掌握的,比如JVM內存模型,垃圾回收機制等等.另外我們還需要掌握一些進行JVM分析的工具.其實在我們安裝JDK的時候,JDK已經為我們準備了許多有用的性能調優監控工具,我們可以看一下JDK安裝目錄下的bin目錄:

  • jps: 主要用來輸出JVM中運行的進程狀態信息
  • jstack: 主要用來查看某個Java進程內的線程堆棧信息
  • jmap: 用來查看堆內存使用狀況,一般結合jhat使用
  • jstat: JVM統計監測工具
  • jconsole: 圖形化的統計工具
  • jvisualvm: 比jconsole功能更強的圖形化的監控工具

  另外我們需要知道,當JVM發生OOM異常時,可以使用命令生成一個.hprof後綴的dump文件,該文件是某個時間節點的heap的快照,我們可以使用VisualVM來查看,也可以用第三方提供的一些工具,比如eclipse的MAT來查看內存溢出的原因.

STW現象

  所謂STW現象(Stop-The-World)是指在執行垃圾收集算法時,Java應用程序的其他所有線程(除了垃圾收集線程之外的線程)都被掛起.此時,系統只允許GC線程繼續運行,其他線程全部暫停,等待GC線程執行完畢后才能繼續執行.這些工作都是由虛擬機在後台自動發起和自動完成的,是在用戶不可見的情況下把用戶正常工作的線程全部停掉,舉個例子,某個接口平時可能只需要50ms的RT,忽然某次調用花費了200ms.因此STW對實時性要求很高的系統來說是難以接受的.

垃圾回收器的種類

  既然有STW現象,那麼有沒有解決方案呢?這就是我們接下來要講的,垃圾回收器的種類,目前為止,JVM一共為我們提供了七種垃圾回收器,其中年輕代有三種,老年代有三種,另外還有一種特殊的G1:

  當然,在更新版本的JDK中還有一種ZGC,為未來垃圾回收器提供了一種趨勢,有興趣的童鞋可以自行了解.

性能調優的目的和具體過程

  有了前面的鋪墊,終於來到了我們最重要的正題:如何進行JVM性能調優?在我看來JVM調優的具體步驟分為如下幾步:

  • 確定調優的目的,選擇合適的GC collector
  • 調整JVM heap的大小
  • 調整young generation在整個JVM heap中所佔的比重.

確定調優的目的,選擇合適的GC collector

  由於每種垃圾回收器的特性並不相同,因此我們需要根據我們的調優目的選擇合適的垃圾回收器,比如,我們需要降低STW的停頓時間,那我們就不能選用串行和并行的垃圾回收器,而應該選用併發的垃圾回收器,即CMS,與之搭配的新生代垃圾回收器就應該選用ParNew.目前一般主流互聯網公司都是用CMS垃圾回收器.

調整JVM heap的大小

  確定了垃圾回收器的類型,就需要調整JVM heap的大小,在這一步的時候,首先我們需要了解JVM相關的一些指令,比如可以在啟動java程序時加上
-XX:+HeapDumpOnOutOfMemoryError,當發生OOM時,JVM會自動為我們生成DUMP文件
-XX:+PrintGCDetails -Xloggc:D:\gclogger\gc.log -XX:+PrintGCDateStamps 生成GC日誌
-Xms2g -Xmx2g 當然,還應該要根據實際情況設置heap的最大最小值,童鞋們要知道,默認情況下,java程序啟動的最小heap大小為1/64物理內存,最大值為1/4物理內存,一般要求我們最大最小值保持一致,避免JVM頻繁擴容和縮容導致不必要的性能浪費.

調整young generation在整個JVM heap中所佔的比重.

  確定了heap的大小,還需要確定新生代的比重
–Xmn1500m -XX:MetaspaceSize=150M

  當然,再厲害的架構師也不可能一次就調整得出最佳的JVM配置參數,而是應該多設置幾組不同的值,放到生產環境(或者和生產環境一樣的環境,比如阿里內部有預發環境,和生產環境保持一致)進行性能測試,通過對比結果得出最佳的JVM性能調優參數,完成JVM性能調優.

總結

  讀完了本篇文章,我相信童鞋們應該或多或少會有些收穫.掌握JVM調整的核心步驟:

  • 確定調優的目的,選擇合適的GC collector
  • 調整JVM heap的大小
  • 調整young generation在整個JVM heap中所佔的比重.
      不了解如何進行JVM的調優的人,把本文內容好好理解后,能讓面試官刮目相看;了解JVM調優,但是條理不清晰的童鞋,可能會對JVM調優有更清晰的認識.總而言之,筆者認為本文是一篇滿滿的乾貨,網上許多講JVM調優的博文,並沒有這麼系統的講解過真正應該如何進行JVM調優.當然筆者能力有限,如文章有錯誤,歡迎指正,畢竟是人就會犯錯.
      PS:一入JVM深似海,從此再也出不來.對JVM有興趣的童鞋,可以鑽研,但是在經驗不足之前,不建議太過深入了解JVM,否則會耽誤自己.當然,立志要成為一名牛逼的架構師,這些都是必須要會的.
      本文我們講完了JVM,下一篇開始,讓我們繼續學習JAVA鎖相關的內容.
      如果覺得博主寫的不錯,歡迎關注博主微信公眾號,博主會不定期分享技術乾貨!

本文由博客一文多發平台 OpenWrite 發布!

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

【其他文章推薦】

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

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

※超省錢租車方案

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

※網頁設計最專業,超強功能平台可客製化

※產品缺大量曝光嗎?你需要的是一流包裝設計!

小師妹學JavaIO之:NIO中那些奇怪的Buffer

目錄

  • 簡介
  • Buffer的分類
  • Big Endian 和 Little Endian
  • aligned內存對齊
  • 總結

簡介

妖魔鬼怪快快顯形,今天F師兄幫助小師妹來斬妖除魔啦,什麼BufferB,BufferL,BufferRB,BufferRL,BufferS,BufferU,BufferRS,BufferRU統統給你剖析個清清楚楚明明白白。

Buffer的分類

小師妹:F師兄不都說JDK源碼是最好的java老師嗎?為程不識源碼,就稱牛人也枉然。但是我最近在學習NIO的時候竟然發現有些Buffer類居然沒有註釋,就那麼突兀的寫在哪裡,讓人好生心煩。

更多內容請訪問www.flydean.com

居然還有這樣的事情?快帶F師兄去看看。

小師妹:F師兄你看,以ShortBuffer為例,它的子類怎麼後面都帶一些奇奇怪怪的字符:

什麼什麼BufferB,BufferL,BufferRB,BufferRL,BufferS,BufferU,BufferRS,BufferRU都來了,點進去看他們的源碼也沒有說明這些類到底是做什麼的。

還真有這種事情,給我一個小時,讓我仔細研究研究。

一個小時后,小師妹,經過我一個小時的辛苦勘察,結果發現,確實沒有官方文檔介紹這幾個類到底是什麼含義,但是師兄我掐指一算,好像發現了這些類之間的小秘密,且聽為兄娓娓道來。

之前的文章,我們講到Buffer根據類型可以分為ShortBuffer,LongBuffer,DoubleBuffer等等。

但是根據本質和使用習慣,我們又可以分為三類,分別是:ByteBufferAsXXXBuffer,DirectXXXBuffer和HeapXXXBuffer。

ByteBufferAsXXXBuffer主要將ByteBuffer轉換成為特定類型的Buffer,比如CharBuffer,IntBuffer等等。

而DirectXXXBuffer則是和虛擬內存映射打交道的Buffer。

最後HeapXXXBuffer是在堆空間上面創建的Buffer。

Big Endian 和 Little Endian

小師妹,F師兄,你剛剛講的都不重要,我就想知道類後面的B,L,R,S,U是做什麼的。

好吧,在給你講解這些內容之前,師兄我給你講一個故事。

話說在明末浙江才女吳絳雪寫過一首詩:《春 景 詩》

鶯啼岸柳弄春晴,
柳弄春晴夜月明。
明月夜晴春弄柳,
晴春弄柳岸啼鶯。

小師妹,可有看出什麼特異之處?最好是多讀幾遍,讀出聲來。

小師妹:哇,F師兄,這首詩從頭到尾和從尾到頭讀起來是一樣的呀,又對稱又有意境!

不錯,這就是中文的魅力啦,根據讀的方式不同,得出的結果也不同,其實在計算機世界也存在這樣的問題。

我們知道在java中底層的最小存儲單元是Byte,一個Byte是8bits,用16進製表示就是Ox00-OxFF。

java中除了byte,boolean是佔一個字節以外,好像其他的類型都會佔用多個字節。

如果以int來舉例,int佔用4個字節,其範圍是從Ox00000000-OxFFFFFFFF,假如我們有一個int=Ox12345678,存到內存地址裏面就有這樣兩種方式。

第一種Big Endian將高位的字節存儲在起始地址

第二種Little Endian將地位的字節存儲在起始地址

其實Big Endian更加符合人類的讀寫習慣,而Little Endian更加符合機器的讀寫習慣。

目前主流的兩大CPU陣營中,PowerPC系列採用big endian方式存儲數據,而x86系列則採用little endian方式存儲數據。

如果不同的CPU架構直接進行通信,就由可能因為讀取順序的不同而產生問題。

java的設計初衷就是一次編寫處處運行,所以自然也做了設計。

所以BufferB表示的是Big Endian的buffer,BufferL表示的是Little endian的Buffer。

而BufferRB,BufferRL表示的是兩種只讀Buffer。

aligned內存對齊

小師妹:F師兄,那這幾個又是做什麼用的呢? BufferS,BufferU,BufferRS,BufferRU。

在講解這幾個類之前,我們先要回顧一下JVM中對象的存儲方式。

還記得我們是怎麼使用JOL來分析JVM的信息的嗎?代碼非常非常簡單:

log.info("{}", VM.current().details());

輸出結果:

# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
# WARNING | Compressed references base/shifts are guessed by the experiment!
# WARNING | Therefore, computed addresses are just guesses, and ARE NOT RELIABLE.
# WARNING | Make sure to attach Serviceability Agent to get the reliable addresses.
# Objects are 8 bytes aligned.
# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

上面的輸出中,我們可以看到:Objects are 8 bytes aligned,這意味着所有的對象分配的字節都是8的整數倍。

再注意上面輸出的一個關鍵字aligned,確認過眼神,是對的那個人。

aligned對齊的意思,表示JVM中的對象都是以8字節對齊的,如果對象本身佔用的空間不足8字節或者不是8字節的倍數,則補齊。

還是用JOL來分析String對象:

[main] INFO com.flydean.JolUsage - java.lang.String object internals:
 OFFSET  SIZE      TYPE DESCRIPTION                               VALUE
      0    12           (object header)                           N/A
     12     4    byte[] String.value                              N/A
     16     4       int String.hash                               N/A
     20     1      byte String.coder                              N/A
     21     1   boolean String.hashIsZero                         N/A
     22     2           (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 2 bytes external = 2 bytes total

可以看到一個String對象佔用24字節,但是真正有意義的是22字節,有兩個2字節是補齊用的。

對齊的好處顯而易見,就是CPU在讀取數據的時候更加方便和快捷,因為CPU設定是一次讀取多少字節來的,如果你存儲是沒有對齊的,則CPU讀取起來效率會比較低。

現在可以回答部分問題:BufferU表示是unaligned,BufferRU表示是只讀的unaligned。

小師妹:那BufferS和BufferRS呢?

這個問題其實還是很難回答的,但是經過師兄我的不斷研究和探索,終於找到了答案:

先看下DirectShortBufferRU和DirectShortBufferRS的區別,兩者的區別在兩個地方,先看第一個Order:

DirectShortBufferRU:

public ByteOrder order() {
        return ((ByteOrder.nativeOrder() != ByteOrder.BIG_ENDIAN)
                ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
    }
DirectShortBufferRS:

public ByteOrder order() {
        return ((ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
                ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
    }

可以看到DirectShortBufferRU的Order是跟nativeOrder是一致的。而DirectShortBufferRS的Order跟nativeOrder是相反的。

為什麼相反?再看兩者get方法的不同:

DirectShortBufferU:

public short get() {
        try {
            checkSegment();
            return ((UNSAFE.getShort(ix(nextGetIndex()))));
        } finally {
            Reference.reachabilityFence(this);
        }
    }
DirectShortBufferS:

public short get() {
        try {
            checkSegment();
            return (Bits.swap(UNSAFE.getShort(ix(nextGetIndex()))));
        } finally {
            Reference.reachabilityFence(this);
        }
    }

區別出來了,DirectShortBufferS在返回的時候做了一個bits的swap操作。

所以BufferS表示的是swap過後的Buffer,和BufferRS表示的是只讀的swap過後的Buffer。

總結

不寫註釋實在是害死人啊!尤其是JDK自己也不寫註釋的情況下!

更多精彩內容且看:

  • 區塊鏈從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特幣等持續更新
  • Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
  • Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
  • java程序員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程

本文作者:flydean程序那些事

本文鏈接:http://www.flydean.com/java-io-nio-kinds-of-buffer/

本文來源:flydean的博客

歡迎關注我的公眾號:程序那些事,更多精彩等着您!

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

【其他文章推薦】

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

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

※回頭車貨運收費標準

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

※超省錢租車方案

※產品缺大量曝光嗎?你需要的是一流包裝設計!

計算機網絡之傳輸層

傳輸層概述

  從信息處理得角度上去看,傳輸層主要是給上面得應用層提供通信服務得。我們平時再對網絡進行編程得時候,我們很多時候都是直接對接得傳輸層,也就是我們使用傳輸層所提供得接口來進行網絡編程,所以我們常說傳輸層是用戶功能得最底層,是面向通信部份得最高層。

  傳輸層負責將上層數據分段並提供端到端的、可靠的或不可靠的傳輸以及端到端的差錯控制和流量控制問題;包含的主要協議:TCP協議(Transmission Control Protocol,傳輸控制協議)、UDP協議(User Datagram Protocol,用戶數據報協議)。

UDP協議

  UDP(User Datagram Protocol: 用戶數據報協議),是一個非常簡單的協議,它對接收到的數據報不合併也不拆分,如下圖:

UDP協議格式:

16位源端口號 16位目的端口號
16位UDP長度 16位UDP校驗和
UDP數據

  UDP協議的特點:UDP是無連接協議;UDP不能保證可靠的交付數據,即UDP協議不會感知網絡是否擁塞,UDP協議不管網絡是否擁塞,都會把數據交付出去,給這個網絡就完了。無法保證數據在網絡中是否丟失;UDP是面向報文傳輸的;UDP沒有擁塞控制,而且UDP首部開銷很小。

TCP協議

  TCP(Transmission Control Protocol: 傳輸控制協議),是計算機網絡中非常複雜的一個協議。

  TCP協議特點:TCP是面向連接的協議;TCP的一個連接有兩端(點對點通信);TCP提供可靠的傳輸服務;TCP協議提供全雙工的通信;TCP是面向字節流的協議。

TCP協議格式:

16位源端口 16位目的端口
序號
確認號
數據偏移 保留字段 TCP標記 窗口
校驗和 緊急指針
TCP選項 填充

序號:0~\(2^{32}\)-1,一個字節一個序號, 數據首字節序號
確認號:0~\(2^{32}\)-1,一個字節一個序號, 期望收到數據的首字節序號。確認號為N:則表示N-1序號的數據都已經收到。
數據偏移:佔4位:0~15,單位為:32位字,數據偏離首部的距離。
TCP標記:佔6位,每位各有不同意義

標記 含義
URG Urgent: 緊急位,URG=1,表示緊急數據
ACK Acknowledgement: 確認位,ACK=1,確認號才生效
PSH Push: 推送位,PSH=1,儘快地把數據交付給應用層
RST Reset: 重置位,RST=1,重新建立連接
SYN Synchronization: 同步位,SYN=1 表示連接請求報文
FIN Finish: 終止位,FIN=1 表示釋放連接

窗口:佔16位:0~\(2^{16}\)-1,窗口指明允許對方發送的數據量
緊急指針:緊急數據(URG=1),指定緊急數據在報文的位置
TCP選項:最多40字節,支持未來的拓展

可靠傳輸的基本原理

  • 停止等待協議:發送方生成新的消息,發送給接收方,並且此時不會產生新的消息,需要收到接受方的確認消息后,才會產生新的消息。超時重傳:如果發送方的消息在傳輸的過程種丟失了,接收方沒有收到消息,就會進行超時重傳;如果接收方發送的確認消息,在傳輸的過程中丟失,也會進行超時重傳,因此 每發送一個消息,都需要設置一個定時器。停止等待協議是最簡單的可靠傳輸協議,但停止等待協議對信道的利用效率不高。
  • 連續ARQ協議:ARQ(Automatic Repeat reQuest:自動重傳請求),由於單個發送和確認效率低,我們可以通過批量發送和確認來提升效率。

  TCP的可靠傳輸基於連續ARQ協議,TCP的滑動窗口以字節為單位,窗口滑動過程如下圖:

如果接收到的序號沒有按序收到確認號,在超時時間內就會進行重新傳送,如下圖:

為了避免對整個窗口中的字節進行重傳,因此TCP協議使用了選擇重傳來提高傳輸效率。選擇重傳:重傳的是一段字節流,而不是某個字節,在TCP選項里存儲的是需要重傳的字節流的邊界。選擇重傳需要指定需要重傳的字節,每一個字節都有唯一的32位序號。

TCP協議的流量控制

   流量控制指讓發送方發送速率不要太快,是使用滑動窗口來實現的,即通過窗口大小控制對方發送速率。當接收到窗口為0的消息,則啟動堅持定時器,堅持定時器每隔一段時間發送一個窗口探測報文。

TCP協議的擁塞控制

  一條數據鏈路經過非常多的設備,數據鏈路中各個部分都有可能成為網路傳輸的瓶頸。流量控制考慮點對點的通信量的控制,擁塞控制考慮整個網絡,是全局性的考慮。如何判斷是否發生了網絡擁塞?根據報文超時來判斷髮生了擁塞是不成立的,如果我們在傳輸的過程中,把光纖或者網絡斷了,這個時候也會導致報文超時,但這是因為網絡故障造成的
  慢啟動算法: 由小到大逐漸增加發送數據量,每收到一個報文確認,就加一。例如:發送的數據量以此為:1 2 4 8 16…,是指數增長的。當使用慢啟動算法增長到慢啟動閾值時,就會使用擁塞避免算法;擁塞避免算法:維護一個擁塞窗口的變量,只要網絡不擁塞,就試探着擁塞窗口調大,如1 2 4 8 16 17 18 19。

TCP連接的建立

標記 含義
URG Urgent: 緊急位,URG=1,表示緊急數據
ACK Acknowledgement: 確認位,ACK=1,確認號才生效
PSH Push: 推送位,PSH=1,儘快地把數據交付給應用層
RST Reset: 重置位,RST=1,重新建立連接
SYN Synchronization: 同步位,SYN=1 表示連接請求報文
FIN Finish: 終止位,FIN=1 表示釋放連接

TCP三次握手的過程:

  1. 第一次握手:建立連接時,客戶端(發送方)發送syn包(seq=j)到服務器,並進入SYN_SENT狀態,等待服務器(接收方)確認;
  2. 第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(seq=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態。
  3. 第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED(TCP連接成功)狀態,完成三次握手

  在客戶端與服務器端傳輸的TCP報文中,雙方的確認號Ack和序號Seq的值,都是在彼此Ack和Seq值的基礎上進行計算的,這樣做保證了TCP報文傳輸的連貫性。一旦出現某一方發出的TCP報文丟失,便無法繼續”握手”,以此確保了”三次握手”的順利完成。此後客戶端和服務器端進行正常的數據傳輸。這就是“三次握手”的過程。

為什麼發送方要發出第三個確認報文呢?

  • 為了避免已經失效的連接請求報文傳送到對方,引起錯誤

TCP連接的釋放

TCP四次揮手的過程:TCP連接斷開過程:假設Client端發起中斷連接請求,也就是發送FIN報文。Server端接到FIN報文後,意思是說”我Client端沒有數據要發給你了”,但是如果你還有數據沒有發送完成,則不必急着關閉Socket,可以繼續發送數據。所以你先發送ACK,”告訴Client端,你的請求我收到了,但是我還沒準備好,請繼續你等我的消息”。這個時候Client端就進入FIN_WAIT狀態,繼續等待Server端的FIN報文。當Server端確定數據已發送完成,則向Client端發送FIN報文,”告訴Client端,好了,我這邊數據發完了,準備好關閉連接了”。Client端收到FIN報文後,”就知道可以關閉連接了,但是他還是不相信網絡,怕Server端不知道要關閉,所以發送ACK後進入TIME_WAIT狀態,如果Server端沒有收到ACK則可以重傳。”,Server端收到ACK后,”就知道可以斷開連接了”。Client端等待了2MSL后依然沒有收到回復,則證明Server端已正常關閉,那好,我Client端也可以關閉連接了。Ok,TCP連接就這樣關閉了!

  MSL(Max Segment Lifetime): 最長報文段壽命,MSL建議設置為2分鐘。為什麼需要等待2MSL?其實在釋放連接的過程中,客戶端最後一次發送的報文,服務端是沒有確認的,為了確保發送方的ACK可以達到接收方,如果2MSL時間內沒有收到,則接收方會重發。這也是等待計時器的作用,主要是為了確保發送方發送的第四次揮手報文可以正確的到達接收方,如果沒有到達的話,接收方就會重新放鬆第三次揮手的報文,以正確得到釋放這次連接。等待計時器的另一個作用就是確保當前連接的所有報文都已經過期。

為什麼關閉連接需要四次揮手呢?
  這是因為服務端的LISTEN狀態下的SOCKET當收到SYN報文的建連請求后,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個報文里來發送。但關閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你所有的數據都全部發送給對方了,所以你可能未必會馬上會關閉SOCKET,也即你可能還需要發送一些數據給對方之後,再發送FIN報文給對方來表示你同意現在可以關閉連接了,所以它這裏的ACK報文和FIN報文多數情況下都是分開發送的。

傳輸層總結:第一個端到端,即主機到主機的層次。傳輸層負責將上層數據分段並提供端到端的、可靠的或不可靠的傳輸。此外,傳輸層還要處理端到端的差錯控制和流量控制問題。 傳輸層的任務是根據通信子網的特性,最佳的利用網絡資源,為兩個端系統的會話層之間,提供建立、維護和取消傳輸連接的功能,負責端到端的可靠數據傳輸。在這一層,信息傳送的協議數據單元稱為段或報文。 網絡層只是根據網絡地址將源結點發出的數據包傳送到目的結點,而傳輸層則負責將數據可靠地傳送到相應的端口。 有關網絡層的重點:

  • 傳輸層負責將上層數據分段並提供端到端的、可靠的或不可靠的傳輸以及端到端的差錯控制和流量控制問題;
  • 包含的主要協議:TCP協議(Transmission Control Protocol,傳輸控制協議)、UDP協議(User Datagram Protocol,用戶數據報協議);
  • 重要設備:網關。

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

※產品缺大量曝光嗎?你需要的是一流包裝設計!

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

唐白鷺訪台東 遍地垃圾接待

摘錄自2020年5月21日中國時報報導

台東好山好水好多垃圾,在太平溪人工溼地執行清理工作的人員,發現溪底有棄置魚網,及玻璃、塑膠袋、鞋子、玻璃瓶垃圾,其中有斑龜等水中生物被魚網纏住死亡;另外,記者也直擊,一隻稀有的唐白鷺在布滿垃圾的利嘉溪出海口覓食,成為極大的諷刺。

過境鳥唐白鷺,已被列為易危物種,全球僅剩不到4000隻。 環保局表示,現場已設立禁止亂丟垃圾的告示牌,但還是有部分民眾無視警告標語隨意丟棄,環保局將加強太平溪人工溼地巡守取締,也呼籲民眾勇於檢舉,如查證屬實,將依廢棄物清理法裁罰1200至6000元罰鍰。

環保局水質保護科表示,為提高民眾對環境保育的重視,減少環境破壞,該局常舉辦巡守隊及解說導覽員的教育訓練課程,希望加強人們守護人工溼地的環境意識;而在利嘉溪出海口部分,則考慮在上游設攔截點,並且加強稽查。

【其他文章推薦】

※廢氣洗滌塔,叫得動, 找得到的專業廠商‎

※市面十大品牌封口機!該如何選購?

※塑膠射出成型加工商品有哪些?

※貨梯使用安全與保養

※掌握產品行銷策略,帶你認識商品包裝設計基本要素