棒球比分直播捷报:BlogJava - 棒球比分大小怎么算|网站//www.355548.live/xiaomage234/生命本就是一次凄美的漂流,記憶中放不下的,永遠是孩提時代的那一份浪漫與純真!zh-cnMon, 26 Oct 2020 06:15:41 GMTMon, 26 Oct 2020 06:15:41 GMT60QoS等級 與 會話[轉] - 棒球比分大小怎么算|网站//www.355548.live/xiaomage234/archive/2020/10/12/435690.html小馬歌小馬歌Mon, 12 Oct 2020 06:19:00 GMT//www.355548.live/xiaomage234/archive/2020/10/12/435690.html//www.355548.live/xiaomage234/comments/435690.html//www.355548.live/xiaomage234/archive/2020/10/12/435690.html#Feedback0//www.355548.live/xiaomage234/comments/commentRss/435690.html//www.355548.live/xiaomage234/services/trackbacks/435690.html

背景

QoS 等級 與 通信的流程有關,直接影響了整個通信。而且篇幅比較長,所以我覺得應該單獨拎出來講一下。

概念

QoS 代表了 服務質量等級。 設置上,由2 位 的二進制控制,且值不允許為 3(0x11)。

QoS值Bit 2Bit 1描述
000最多分發一次
101至少分發一次
210只分發一次
-11保留位

要注意的是,QoS 是 Sender 和 Receiver 之間達成的協議,不是 Publisher 和 Subscriber 之間達成的協議。

也就是說 Publisher 發布一條 QoS1 的消息,只能保證 Broker 能至少收到一次這個消息;至于對應的 Subscriber 能否至少收到一次這個消息,還要取決于 Subscriber 在 Subscribe 的時候和 Broker 協商的 QoS 等級。

這里又牽扯出一個概念:"QoS 降級":在 MQTT 協議中,從 Broker 到 Subscriber 這段消息傳遞的實際 QoS 等于 "Publisher 發布消息時指定的 QoS 等級和 Subscriber 在訂閱時與 Broker 協商的 QoS 等級,這兩個 QoS 等級中的最小那一個。"

QoS 0 的通信時序圖

此時,整個過程中的 Sender 不關心 Receiver 是否收到消息,它"盡力"發完消息,至于是否有人收到,它不在乎。

發布者服務器訂閱者PUBLISH (QoS0,Msg-A)PUBLISH(QoS0,Msg-A)Delete Msg-A發布者服務器訂閱者QoS 0:At most one(Fire and forget)

QoS1 的通信時序圖

此時,Sender 發送的一條消息,Receiver 至少能收到一次,也就是說 Sender 向 Receiver 發送消息,如果發送失敗,會繼續重試,直到 Receiver 收到消息為止,但是因為重傳的原因,Receiver 有可能會收到重復的消息;

發布者服務器訂閱者Store (Msg-A)PUBLISH (QoS1,Msg-A)Store (Msg-A)PUBLISH (QoS1,Msg-A)PUBACK (QoS1)Delete (Msg-A)PUBACK (QoS1,Msg-A)Delete (Msg-A)發布者服務器訂閱者QoS 1:At least one

1)Sender 向 Receiver 發送一個帶有消息數據的 PUBLISH 包, 并在本地保存這個 PUBLISH 包。

2)Receiver 收到 PUBLISH 包以后,向 Sender 發送一個 PUBACK 數據包,PUBACK 數據包沒有消息體(Payload),在可變頭中(Variable header)中有一個包標識(Packet Identifier),和它收到的 PUBLISH 包中的 Packet Identifier 一致。

3)Sender 收到 PUBACK 之后,根據 PUBACK 包中的 Packet Identifier 找到本地保存的 PUBLISH 包,然后丟棄掉,一次消息的發送完成。

4)如果 Sender 在一段時間內沒有收到 PUBLISH 包對應的 PUBACK,它將該 PUBLISH 包的 DUP 標識設為 1(代表是重新發送的 PUBLISH 包),然后重新發送該 PUBLISH 包。重復這個流程,直到收到 PUBACK,然后執行第 3 步。

QoS 2 的通信時序圖

QoS2 不僅要確保 Receiver 能收到 Sender 發送的消息,還要保證消息不重復。它的重傳和應答機制就要復雜一些,同時開銷也是最大的。

Sender 發送的一條消息,Receiver 確保能收到而且只收到一次,也就是說 Sender 盡力向 Receiver 發送消息,如果發送失敗,會繼續重試,直到 Receiver 收到消息為止,同時保證 Receiver 不會因為消息重傳而收到重復的消息。

發布者服務器訂閱者Store (Msg-A)PUBLISH (QoS2,Msg-A,DUP=0)Store (Msg-A)PUBREC (QoS2,Msg-A)PUBREL (QoS2,Msg-A)PUBLISH (QoS2,Msg-A,DUP=0)PUBCOMP (QoS2,Msg-A)Delete (Msg-A)Store (Msg-A)PUBREC (QoS2,Msg-A)PUBREL (QoS2,Msg-A)Notify (Msg-A)PUBCOMP (QoS2,Msg-A)Delete (Msg-A)Delete (Msg-A)發布者服務器訂閱者QoS 2:Exactly one

QoS 使用 2 套請求/應答流程(一個 4 段的握手)來確保 Receiver 收到來自 Sender 的消息,且不重復:

1)Sender 發送 QoS 為 2 的 PUBLISH 數據包,數據包 Packet Identifier 為 P,并在本地保存該 PUBLISH 包;

2)Receiver 收到 PUBLISH 數據包以后,在本地保存 PUBLISH 包的 Packet Identifier P,并回復 Sender 一個 PUBREC 數據包,PUBREC 數據包可變頭中的 Packet Identifier 為 P,沒有消息體(Payload);

3)當 Sender 收到 PUBREC,它就可以安全地丟棄掉初始的 Packet Identifier 為 P 的 PUBLISH 數據包,同時保存該 PUBREC 數據包,同時回復 Receiver 一個 PUBREL 數據包,PUBREL 數據包可變頭中的 Packet Identifier 為 P,沒有消息體;如果 Sender 在一定時間內沒有收到 PUBREC,它會把 PUBLISH 包的 DUP 標識設為 1,重新發送該 PUBLISH 數據包(Payload);

4)當 Receiver 收到 PUBREL 數據包,它可以丟棄掉保存的 PUBLISH 包的 Packet Identifier P,并回復 Sender 一個 PUBCOMP 數據包,PUBCOMP 數據包可變頭中的 Packet Identifier 為 P,沒有消息體(Payload);

5)當 Sender 收到 PUBCOMP 包,那么它認為數據包傳輸已完成,它會丟棄掉對應的 PUBREC 包。如果 Sender 在一定時間內沒有收到 PUBCOMP 包,它會重新發送 PUBREL 數據包。

我們可以看到在 QoS2 中,完成一次消息的傳遞,Sender 和 Reciever 之間至少要發送四個數據包,QoS2 是最安全也是最慢的一種 QoS 等級了。

QoS 和會話(Session)

客戶端的會話狀態包括:

  • 已經發送給服務端,但是還沒有完成確認的QoS 1和QoS 2級別的消息
  • 已從服務端接收,但是還沒有完成確認的QoS 2級別的消息。

服務端的會話狀態包括:

  • 會話是否存在,即使會話狀態的其它部分都是空。
  • 客戶端的訂閱信息。
  • 已經發送給客戶端,但是還沒有完成確認的QoS 1和QoS 2級別的消息。
  • 即將傳輸給客戶端的QoS 1和QoS 2級別的消息。
  • 已從客戶端接收,但是還沒有完成確認的QoS 2級別的消息。
  • 可選,準備發送給客戶端的QoS 0級別的消息。

保留消息不是服務端會話狀態的一部分,會話終止時不能刪除保留消息。

如果 Client 想接收離線消息,必須使用持久化的會話(CONNECT報文中可變頭(byte8[1])Clean Session = 0)連接到 Broker,這樣 Broker 才會存儲 Client 在離線期間沒有確認接收的 QoS 大于 1 的消息。

QoS 等級的選擇

在以下情況下你可以選擇 QoS0

  • Client 和 Broker 之間的網絡連接非常穩定,例如一個通過有線網絡連接到 Broker 的測試用 Client;
  • 可以接受丟失部分消息,比如你有一個傳感器以非常短的間隔發布狀態數據,所以丟一些也可以接受;
  • 你不需要離線消息。

在以下情況下你應該選擇 QoS1:

  • 你需要接收所有的消息,而且你的應用可以接受并處理重復的消息;
  • 你無法接受 QoS2 帶來的額外開銷,QoS1 發送消息的速度比 QoS2 快很多。

在以下情況下你應該選擇 QoS2:

  • 你的應用必須接收到所有的消息,而且你的應用在重復的消息下無法正常工作,同時你也能接受 QoS2 帶來的額外開銷。

實際上,QoS1 是應用最廣泛的 QoS 等級,QoS1 發送消息的速度很快,而且能夠保證消息的可靠性。雖然使用 QoS1 可能會收到重復的消息,但是在應用程序里面處理重復消息,通常并不是件難事。



小馬歌 2020-10-12 14:19 發表評論
]]>
性能問題定位:工具使用【轉】 - 棒球比分大小怎么算|网站//www.355548.live/xiaomage234/archive/2019/04/19/433725.html小馬歌小馬歌Fri, 19 Apr 2019 03:04:00 GMT//www.355548.live/xiaomage234/archive/2019/04/19/433725.html//www.355548.live/xiaomage234/comments/433725.html//www.355548.live/xiaomage234/archive/2019/04/19/433725.html#Feedback0//www.355548.live/xiaomage234/comments/commentRss/433725.html//www.355548.live/xiaomage234/services/trackbacks/433725.html//zhulongchao.com/blog/performance-trace.html

1.網速測試

安裝iperf

yum install epel-release 從epel源中安裝 yum install -y  iperf 

帶寬檢測

iperf -s 開啟服務端  iperf -c ip 

丟包問題

tcpdump進行抓包  tcpdump -i eth0 -s 3000 port 8080 -w /home/tomcat.pcap  對于抓包文件采用wireshark進行分析  丟包(TCP DUP ACK) 重傳(retransmission),超時重傳, 

2.cdn性能測試

cdn 緩存,回源問題    304請求,瀏覽器是否使用本地緩存。比較last_modified 和if_modified_since  通過實踐戳來判斷,瀏覽器緩存和cdn緩存 

3.DNS基礎

路由解析

泛域名解析

4.分布式服務鏈路追蹤

http入口產生一個traceId  分發到rpc調用,cache,db,jms調用鏈路中  google的著名論文dapper和zipkin  日志聚合,綁定鏈路日志和業務日志  采樣采集,慢請求,異常服務。  日志量大。日志異步寫入,環狀數組,日志組件自研  共享信息放在ThreadLocal中。比如traceId 

5.網卡性能問題定位

tsar -l  -i 1 --traffic 查看網卡的進出流量 

6.CPU性能問題定位

tsar -l  -i 1 --cpu  軟件問題定位,perf 采樣所有進程數據  perf record -F 99 -a -g -- sleep 30  java進程的函數map:java -cp attach-main.jar:$JAVA_HOME/lib/tools.jar net.virtualvoid.perf.AttachOnce PID  輸出函數和地址的map  輸出火焰圖 perf script | stackcollapse-perf.pl | flamegraph.pl --color=java --hash > flamegraph.svg 

7.內存性能問題定位

-堆內內存問題,

采用jmap dump內存,采用離線工具分析  jprofile、mat 

-堆外內存問題

a.google-perftools

yum install -y google-perftools graphviz  export LD_PRELOAD=/usr/lib64/libtcmalloc.so.4  export HEAPPROFILE=/home/testGperf.prof  執行程序,結束程序,生成prof  分析prof  生成svg, pdf,text pprof --svg $JAVA_HOME/bin/java testGperf.prof.0001.heap > test.svg  pprof --pdf $JAVA_HOME/bin/java testGperf.prof.0001.heap > test.pdf  pprof --text $JAVA_HOME/bin/java testGperf.prof.0001.heap > test.txt 

b.jemalloc定位(優勢,適合長時間trace)

sudo apt-get install graphviz 編譯安裝 ./configure –enable-prof –enable-stats –enable-debug –enable-fill make make install

運行配置 export MALLOC_CONF=”prof:true,prof_gdump:true,prof_prefix:/home/jedump/jez,lg_prof_interval:30,lg_prof_sample:17”

export LD_PRELOAD=/usr/local/lib/libjemalloc.so.2 運行 java -jar target/spring-boot-jemalloc-example-0.0.1-SNAPSHOT.jar

jeprof –show_bytes –svg jez.*.heap > app-profiling.svg

注明:如果在docker容器中,推薦用pprof,jemalloc只顯示函數地址,不顯示函數名

8.機器資源配額問題

/etc/security/limits.conf

  • soft nofile 65536
  • hard nofile 65536

控制該用戶文件句柄數

9.磁盤性能問題定位

tsar -l -i 1 –io



小馬歌 2019-04-19 11:04 發表評論
]]>
Java堆外內存排查小結【轉】 - 棒球比分大小怎么算|网站//www.355548.live/xiaomage234/archive/2019/03/30/433695.html小馬歌小馬歌Sat, 30 Mar 2019 03:44:00 GMT//www.355548.live/xiaomage234/archive/2019/03/30/433695.html//www.355548.live/xiaomage234/comments/433695.html//www.355548.live/xiaomage234/archive/2019/03/30/433695.html#Feedback0//www.355548.live/xiaomage234/comments/commentRss/433695.html//www.355548.live/xiaomage234/services/trackbacks/433695.htmlhttps://blog.csdn.net/lycyingO/article/details/80854669


 版權聲明:微信公眾號《小姐姐味道》,轉載注明出處 https://blog.csdn.net/lycyingO/article/details/80854669
簡介
JVM堆外內存難排查但經?;岢魷治侍?,這可能是目前最全的JVM堆外內存排查思路。
通過本文,你應該了解:
pmap 命令
gdb 命令
perf 命令
內存 RSS、VSZ的區別
java NMT
起因
這幾天遇到一個比較奇怪的問題,覺得有必要和大家分享一下。我們的一個服務,運行在docker上,在某個版本之后,占用的內存開始增長,直到docker分配的內存上限,但是并不會OOM。版本的更改如下:
升級了基礎軟件的版本
將docker的內存上限由4GB擴展到8GB
上上個版本的一項變動是使用了EhCache的Heap緩存
沒有讀文件,也沒有mmap操作
使用jps 查看啟動參數,發現分配了大約3GB的堆內存
[root]$ jps -v
75 Bootstrap -Xmx3000m -Xms3000m  -verbose:gc -Xloggc:/home/logs/gc.log -XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSCompactAtFullCollection -XX:MaxTenuringThreshold=10 -XX:MaxPermSize=128M -XX:SurvivorRatio=3 -XX:NewRatio=2 -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
使用ps查看進程使用的內存和虛擬內存 ( Linux內存管理 )。除了虛擬內存比較高達到17GB以外,實際使用的內存RSS也夸張的達到了7GB,遠遠超過了-Xmx的設定。
[root]$ ps -p 75 -o rss,vsz  
 
RSS    VSZ 7152568 17485844
原創文章,轉載注明出處 (//sayhiai.com)
排查過程
明顯的,是有堆外內存的使用,不太可能是由于EhCache引起的(因為我們使用了heap方式)。了解到基礎軟件的升級涉及到netty版本升級,netty會用到一些DirectByteBuffer,第一輪排查我們采用如下方式:
jmap -dump:format=b,file=75.dump 75 通過分析堆內存找到DirectByteBuffer的引用和大小
部署一個升級基礎軟件之前的版本,持續觀察
部署另一個版本,更改EhCache限制其大小到1024M
考慮到可能由Docker的內存分配機制引起,部署一實例到實體機
結果4個環境中的服務,無一例外的都出現了內存超用的問題。問題很奇怪,寶寶睡不著覺。
pmap
為了進一步分析問題,我們使用pmap查看進程的內存分配,通過RSS升序序排列。結果發現除了地址000000073c800000上分配的3GB堆以外,還有數量非常多的64M一塊的內存段,還有巨量小的物理內存塊映射到不同的虛擬內存段上。但到現在為止,我們不知道里面的內容是什么,是通過什么產生的。
[root]$ pmap -x 75  | sort -n -k3
 
.....省略N行
 
0000000040626000   55488   55484   55484 rwx--    [ anon ]
 
00007fa07c000000   65536   55820   55820 rwx--    [ anon ]
 
00007fa044000000   65536   55896   55896 rwx--    [ anon ]
 
00007fa0c0000000   65536   56304   56304 rwx--    [ anon ]
 
00007f9db8000000   65536   56360   56360 rwx--    [ anon ]
 
00007fa0b8000000   65536   56836   56836 rwx--    [ anon ]
 
00007fa084000000   65536   57916   57916 rwx--    [ anon ]
 
00007f9ec4000000   65532   59752   59752 rwx--    [ anon ]
 
00007fa008000000   65536   60012   60012 rwx--    [ anon ]
 
00007f9e58000000   65536   61608   61608 rwx--    [ anon ]
 
00007f9f18000000   65532   61732   61732 rwx--    [ anon ]
 
00007fa018000000   65532   61928   61928 rwx--    [ anon ]
 
00007fa088000000   65536   62336   62336 rwx--    [ anon ]
 
00007fa020000000   65536   62428   62428 rwx--    [ anon ]
 
00007f9e44000000   65536   64352   64352 rwx--    [ anon ]
 
00007f9ec0000000   65528   64928   64928 rwx--    [ anon ]
 
00007fa050000000   65532   65424   65424 rwx--    [ anon ]
 
00007f9e08000000   65512   65472   65472 rwx--    [ anon ]
 
00007f9de0000000   65524   65512   65512 rwx--    [ anon ]
 
00007f9dec000000   65532   65532   65532 rwx--    [ anon ]
 
00007f9dac000000   65536   65536   65536 rwx--    [ anon ]
 
00007f9dc8000000   65536   65536   65536 rwx--    [ anon ]
 
00007f9e30000000   65536   65536   65536 rwx--    [ anon ]
 
00007f9eb4000000   65536   65536   65536 rwx--    [ anon ]
 
00007fa030000000   65536   65536   65536 rwx--    [ anon ]
 
00007fa0b0000000   65536   65536   65536 rwx--    [ anon ]
 
000000073c800000 3119140 2488596 2487228 rwx--    [ anon ]
 
total kB        17629516 7384476 7377520
通過google,找到以下資料 Linux glibc >= 2.10 (RHEL 6) malloc may show excessive virtual memory usage)
文章指出造成應用程序大量申請64M大內存塊的原因是由Glibc的一個版本升級引起的,通過export MALLOC_ARENA_MAX=4可以解決VSZ占用過高的問題。雖然這也是一個問題,但卻不是我們想要的,因為我們增長的是物理內存,而不是虛擬內存。
NMT
幸運的是 JDK1.8有Native Memory Tracker可以幫助定位。通過在啟動參數上加入-XX:NativeMemoryTracking=detail就可以啟用。在命令行執行jcmd可查看內存分配。
#jcmd 75 VM.native_memory summary
 
Native Memory Tracking: Total: reserved=5074027KB, committed=3798707KB -                 Java Heap (reserved=3072000KB, committed=3072000KB)                            (mmap: reserved=3072000KB, committed=3072000KB) -                     Class (reserved=1075949KB, committed=28973KB)                            (classes #4819)                            (malloc=749KB #13158)                            (mmap: reserved=1075200KB, committed=28224KB) -                    Thread (reserved=484222KB, committed=484222KB)                            (thread #470)                            (stack: reserved=482132KB, committed=482132KB)                            (malloc=1541KB #2371)                            (arena=550KB #938) -                      Code (reserved=253414KB, committed=25070KB)                            (malloc=3814KB #5593)                            (mmap: reserved=249600KB, committed=21256KB) -                        GC (reserved=64102KB, committed=64102KB)                            (malloc=54094KB #255)                            (mmap: reserved=10008KB, committed=10008KB) -                  Compiler (reserved=542KB, committed=542KB)                            (malloc=411KB #543)                            (arena=131KB #3) -                  Internal (reserved=50582KB, committed=50582KB)                            (malloc=50550KB #13713)                            (mmap: reserved=32KB, committed=32KB) -                    Symbol (reserved=6384KB, committed=6384KB)                            (malloc=4266KB #31727)                            (arena=2118KB #1) -    Native Memory Tracking (reserved=1325KB, committed=1325KB)                            (malloc=208KB #3083)                            (tracking overhead=1117KB) -               Arena Chunk (reserved=231KB, committed=231KB)                            (malloc=231KB) -                   Unknown (reserved=65276KB, committed=65276KB)                            (mmap: reserved=65276KB, committed=65276KB)
雖然pmap得到的內存地址和NMT大體能對的上,但仍然有不少內存去向成謎。雖然是個好工具但問題并不能解決。
gdb
非常好奇64M或者其他小內存塊中是什么內容,接下來通過gdbdump出來。讀取/proc目錄下的maps文件,能精準的知曉目前進程的內存分布。
以下腳本通過傳入進程id,能夠將所關聯的內存全部dump到文件中(會影響服務,慎用)。
grep rw-p /proc/$1/maps | sed -n 's/^\([0-9a-f]*\)-\([0-9a-f]*\) .*$/\1 \2/p' | while read start stop; do gdb --batch --pid $1 -ex "dump memory $1-$start-$stop.dump 0x$start 0x$stop"; done
更多時候,推薦之dump一部分內存。(再次提醒操作會影響服務,注意dump的內存塊大小,慎用)。
gdb --batch --pid 75 -ex "dump memory a.dump 0x7f2bceda1000 0x7f2bcef2b000
[root]$ du -h *
dump 4.0K
55-00600000-00601000.dump 400K
55-00eb7000-00f1b000.dump 0
55-704800000-7c0352000.dump 47M
55-7f2840000000-7f2842eb8000.dump 53M
55-7f2848000000-7f284b467000.dump 64M
55-7f284c000000-7f284fffa000.dump 64M
55-7f2854000000-7f2857fff000.dump 64M
55-7f285c000000-7f2860000000.dump 64M
55-7f2864000000-7f2867ffd000.dump 1016K
55-7f286a024000-7f286a122000.dump 1016K
55-7f286a62a000-7f286a728000.dump 1016K
55-7f286d559000-7f286d657000.dump
是時候查看里面的內容了
[root]$ view 55-7f284c000000-7f284fffa000.dump
^@^@X+^?^@^@^@^@^@d(^?^@^@^@ ÿ^C^@^@^@^@^@ ÿ^C^@^@^@^@^@^@^@^@^@^@^@^@±<97>p^C^@^@^@^@ 8^^Z+^?^@^@ ^@^@d(^?^@^@ 8^^Z+^?^@^@ ^@^@d(^?^@^@
achine":524993642,"timeSecond":1460272569,"inc":2145712868,"new":false},"device":{"client":"android","uid":"xxxxx","version":881},"
device_android":{"BootSerialno":"xxxxx","CpuInfo":"0-7","MacInfo":"2c:5b:b8:b0:d5:10","RAMSize":"4027212","SdcardInfo":"xxxx","Serialno":"xxxx",
"android_id":"488aedba19097476","buildnumber":"KTU84P/1416486236","device_ip":"0.0.0.0","mac":"2c:5b:b8:b0:d5:10","market_source":"12","model":"OPPO ...more
納尼?這些內容不應該在堆里面么?為何還會使用額外的內存進行分配?上面已經排查netty申請directbuffer的原因了,那么還有什么地方在分配堆外內存呢?
perf
傳統工具失靈,快到了黔驢技窮的時候了,是時候祭出神器perf了。
使用 perf record -g -p 55 開啟監控棧函數調用。運行一段時間后Ctrl+C結束,會生成一個文件perf.data。
執行perf report -i perf.data查看報告。
如圖,進程大量執行bzip相關函數。搜索zip,結果如下:
-.-!
進程調用了Java_java_util_zip_Inflater_inflatBytes() 申請了內存,僅有一小部分調用Deflater釋放內存。與pmap內存地址相比對,確實是bzip在搞鬼。
原創文章,轉載注明出處 (//sayhiai.com)
解決
java項目搜索zip定位到代碼,發現確實有相關bzip壓縮解壓操作,而且GZIPInputStream有個地方沒有close。
GZIPInputStream使用Inflater申請堆外內存,Deflater釋放內存,調用close()方法來主動釋放。如果忘記關閉,Inflater對象的生命會延續到下一次GC。在此過程中,堆外內存會一直增長。
原代碼:
public byte[] decompress ( byte[] input) throws IOException {
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                IOUtils.copy(new GZIPInputStream(new ByteArrayInputStream(input)), out);
                return out.toByteArray();
            }
修改后:
 public byte[] decompress(byte[] input) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(input));
        IOUtils.copy(gzip, out);
        gzip.close();
        return out.toByteArray();
    }
經觀察,問題解決。
--------------------- 
作者:lycyingO 
來源:CSDN 
原文:https://blog.csdn.net/lycyingO/article/details/80854669 
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


小馬歌 2019-03-30 11:44 發表評論
]]>
POSIX 線程詳解- 一種支持內存共享的簡捷工具【轉】 - 棒球比分大小怎么算|网站//www.355548.live/xiaomage234/archive/2019/02/16/433640.html小馬歌小馬歌Sat, 16 Feb 2019 03:37:00 GMT//www.355548.live/xiaomage234/archive/2019/02/16/433640.html//www.355548.live/xiaomage234/comments/433640.html//www.355548.live/xiaomage234/archive/2019/02/16/433640.html#Feedback0//www.355548.live/xiaomage234/comments/commentRss/433640.html//www.355548.live/xiaomage234/services/trackbacks/433640.html閱讀全文

小馬歌 2019-02-16 11:37 發表評論
]]>
MySQL加鎖分析【轉】 - 棒球比分大小怎么算|网站//www.355548.live/xiaomage234/archive/2019/02/13/433636.html小馬歌小馬歌Wed, 13 Feb 2019 09:07:00 GMT//www.355548.live/xiaomage234/archive/2019/02/13/433636.html//www.355548.live/xiaomage234/comments/433636.html//www.355548.live/xiaomage234/archive/2019/02/13/433636.html#Feedback0//www.355548.live/xiaomage234/comments/commentRss/433636.html//www.355548.live/xiaomage234/services/trackbacks/433636.html閱讀全文

小馬歌 2019-02-13 17:07 發表評論
]]>
MySQL 小心使用 replace into【轉】 - 棒球比分大小怎么算|网站//www.355548.live/xiaomage234/archive/2018/12/25/433561.html小馬歌小馬歌Tue, 25 Dec 2018 11:19:00 GMT//www.355548.live/xiaomage234/archive/2018/12/25/433561.html//www.355548.live/xiaomage234/comments/433561.html//www.355548.live/xiaomage234/archive/2018/12/25/433561.html#Feedback0//www.355548.live/xiaomage234/comments/commentRss/433561.html//www.355548.live/xiaomage234/services/trackbacks/433561.html摘要: MySQL replace into 錯誤案例 背景 * MySQL5.7 * ROW模式 * 表結構 CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `col_1` varc

棒球比分直播捷报:MySQL replace into 錯誤案例

背景

* MySQL5.7  * ROW模式   * 表結構 CREATE TABLE `test` (   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,   `col_1` varchar(100) DEFAULT NULL,   `col_2` varchar(100) DEFAULT NULL,   `col_3` varchar(100) DEFAULT NULL,   PRIMARY KEY (`id`),   UNIQUE KEY `col_1` (`col_1`) ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 

錯誤場景一

其他字段value莫名其妙的沒了

  • step1 初始化記錄
mater:lc> REPLACE INTO test (col_1,col_2,col_3) values('a','a','a'); Query OK, 1 row affected (0.00 sec) --注意,這里是影響了1條記錄  master:lc> REPLACE INTO test (col_1,col_2,col_3) values('b','b','b'); Query OK, 1 row affected (0.00 sec) --注意,這里是影響了1條記錄  master:lc> REPLACE INTO test (col_1,col_2,col_3) values('c','c','c'); Query OK, 1 row affected (0.00 sec) --注意,這里是影響了1條記錄   master > show create table test  | test  | CREATE TABLE `test` (   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,   `col_1` varchar(100) DEFAULT NULL,   `col_2` varchar(100) DEFAULT NULL,   `col_3` varchar(100) DEFAULT NULL,   PRIMARY KEY (`id`),   UNIQUE KEY `col_1` (`col_1`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 |   mater > select * from test; +----+-------+-------+-------+ | id | col_1 | col_2 | col_3 | +----+-------+-------+-------+ |  1 | a     | a     | a     | |  2 | b     | b     | b     | |  3 | c     | c     | c     | +----+-------+-------+-------+ 3 rows in set (0.00 sec)  
  • step2 構造錯誤場景
master:lc> replace into test(col_1,col_2) values('c','cc'); Query OK, 2 rows affected (0.00 sec)  dba:lc> select * from test; +----+-------+-------+-------+ | id | col_1 | col_2 | col_3 | +----+-------+-------+-------+ |  1 | a     | a     | a     | |  2 | b     | b     | b     | |  4 | c     | cc    | NULL  | +----+-------+-------+-------+ 3 rows in set (0.00 sec)  
  • 總結
  1. col_3 的值,從原來的c,變成了NULL,天吶,數據不見了。 id 也變了。
  2. 用戶原本的需求,應該是如果col_1='c' 存在,那么就改變col_2='cc',其余的記錄保持不變,結果id,col_3都變化了
  3. 解決方案就是:將replace into 改成 INSERT INTO … ON DUPLICATE KEY UPDATE

但是你以為這樣就完美的解決了嗎? 馬上就會帶來另外一場災難,請看下面的錯誤場景

錯誤場景二

ERROR 1062 (23000): Duplicate entry 'x' for key 'PRIMARY'

  • step1 初始化記錄
 mater:lc> REPLACE INTO test (col_1,col_2) values('a','a'); Query OK, 1 row affected (0.00 sec) --注意,這里是影響了1條記錄  master:lc> REPLACE INTO test (col_1,col_2) values('b','b'); Query OK, 1 row affected (0.00 sec) --注意,這里是影響了1條記錄  master:lc> REPLACE INTO test (col_1,col_2) values('c','c'); Query OK, 1 row affected (0.00 sec) --注意,這里是影響了1條記錄   master > show create table test  | test  | CREATE TABLE `test` (   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,   `col_1` varchar(100) DEFAULT NULL,   `col_2` varchar(100) DEFAULT NULL,   PRIMARY KEY (`id`),   UNIQUE KEY `col_1` (`col_1`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 |   slave > show create table test  | test  | CREATE TABLE `test` (   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,   `col_1` varchar(100) DEFAULT NULL,   `col_2` varchar(100) DEFAULT NULL,   PRIMARY KEY (`id`),   UNIQUE KEY `col_1` (`col_1`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 |
  • step2 構造錯誤場景
* master  mater:lc> REPLACE INTO test (col_1,col_2) values('c','cc'); Query OK, 2 rows affected (0.00 sec)  --注意,這里是影響了兩條記錄  mater:lc> show create table test  | test  | CREATE TABLE `test` (   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,   `col_1` varchar(100) DEFAULT NULL,   `col_2` varchar(100) DEFAULT NULL,   PRIMARY KEY (`id`),   UNIQUE KEY `col_1` (`col_1`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 |  master:lc> select * from test +----+-------+-------+ | id | col_1 | col_2 | +----+-------+-------+ |  1 | a     | a     | |  2 | b     | b     | |  4 | c     | cc    | +----+-------+-------+ 3 rows in set (0.00 sec)  * slave  slave:lc> show create table test  | test  | CREATE TABLE `test` (   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,   `col_1` varchar(100) DEFAULT NULL,   `col_2` varchar(100) DEFAULT NULL,   PRIMARY KEY (`id`),   UNIQUE KEY `col_1` (`col_1`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 |  slave:lc> select * from test +----+-------+-------+ | id | col_1 | col_2 | +----+-------+-------+ |  1 | a     | a     | |  2 | b     | b     | |  4 | c     | cc    | +----+-------+-------+ 3 rows in set (0.00 sec) 
  • step3 錯誤案例產生
* 假設有一天,master 掛了, 由slave 提升為 new mater  原slave:lc> show create table test  | test  | CREATE TABLE `test` (   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,   `col_1` varchar(100) DEFAULT NULL,   `col_2` varchar(100) DEFAULT NULL,   PRIMARY KEY (`id`),   UNIQUE KEY `col_1` (`col_1`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 |  原slave:lc> select * from test +----+-------+-------+ | id | col_1 | col_2 | +----+-------+-------+ |  1 | a     | a     | |  2 | b     | b     | |  4 | c     | cc    | +----+-------+-------+ 3 rows in set (0.00 sec)   ===注意==  root:lc> REPLACE INTO test (col_1,col_2) values('d','d'); ERROR 1062 (23000): Duplicate entry '4' for key 'PRIMARY'  
  • 總結
* Row 模式,主從情況下,replace into 和 INSERT INTO … ON DUPLICATE KEY UPDATE 都會導致以上問題的發生 * 解決方案: 最后可以通過alter table auto_increment值解決,但是這樣已經造成mater的表很長時間沒有寫入了。。。

最后總結

  • replace with unique key
1. 禁止 replace into (錯誤一,錯誤二 都會發生) 2. 禁止 INSERT INTOON DUPLICATE KEY UPDATE (錯誤二 會發生)
  • replace with primary key
1. 禁止 replace into (會發生錯誤場景一的案例,丟失部分字段數據) 2. 可以使用INSERT INTOON DUPLICATE KEY UPDATE 代替 replace into


小馬歌 2018-12-25 19:19 發表評論
]]>
MySQL 開發實踐 8 問,你能 hold 住幾個?【轉】 - 棒球比分大小怎么算|网站//www.355548.live/xiaomage234/archive/2018/12/03/433534.html小馬歌小馬歌Mon, 03 Dec 2018 07:55:00 GMT//www.355548.live/xiaomage234/archive/2018/12/03/433534.html//www.355548.live/xiaomage234/comments/433534.html//www.355548.live/xiaomage234/archive/2018/12/03/433534.html#Feedback0//www.355548.live/xiaomage234/comments/commentRss/433534.html//www.355548.live/xiaomage234/services/trackbacks/433534.html閱讀全文

小馬歌 2018-12-03 15:55 發表評論
]]>
推薦幾本學習MySQL的好書【轉】 - 棒球比分大小怎么算|网站//www.355548.live/xiaomage234/archive/2018/12/03/433533.html小馬歌小馬歌Mon, 03 Dec 2018 07:54:00 GMT//www.355548.live/xiaomage234/archive/2018/12/03/433533.html//www.355548.live/xiaomage234/comments/433533.html//www.355548.live/xiaomage234/archive/2018/12/03/433533.html#Feedback0//www.355548.live/xiaomage234/comments/commentRss/433533.html//www.355548.live/xiaomage234/services/trackbacks/433533.html

我這里推薦幾本MySQL的好書,應該能夠有效避免學習MySQL的彎路,并且達到一個不錯的水平。 我這里推薦的書或材料分為兩個部分,分別是MySQL的使用和MySQL的源碼學習。在介紹的過程中,我會穿插簡單的評語或感想。

1.MySQL的使用

1.1 MySQL技術內幕:InnoDB存儲引擎

學習MySQL的使用,首推姜承堯的《MySQL技術內幕:InnoDB存儲引擎》,當然不是因為姜sir是我的經理才推薦這本書。這本書確實做到了由漸入深、深入淺出,是中國人寫的最贊的MySQL技術書籍,符合國人的思維方式和閱讀習慣,而且,這本書簡直就是面試寶典,對于近期有求職MySQL相關崗位的朋友,可以認真閱讀,對找工作有很大的幫助。當然,也有人說這本書入門難度較大,這個就自己取舍了,個人建議就以這本書入門即可,有不懂的地方可以求助官方手冊和google。

MySQL技術內幕

1.2 MySQL的官方手冊

我剛開始學習MySQL的時候誤區就是,沒有好好閱讀MySQL的官方手冊。例如,我剛開始很難理解InnoDB的鎖,尤其是各個情況下如何加鎖,這個問題在我師弟進入百度做DBA時,也困擾了他一陣子,我們兩還討論來討論去,其實,MySQL官方手冊已經寫得清清楚楚,什么樣的SQL語句加什么樣的鎖,當然,MySQL的官方手冊非常龐大,一時半會很難看完,建議先看InnoDB相關的部分。

//dev.mysql.com/doc/refman/5.7/en/innodb-storage-engine.html

1.3 MySQL排錯指南

MySQL排錯指南》是2015年夏天引入中國的書籍,這本書可以說是DBA速成指南,介紹的內容其實比較簡單,但是也非常實用,對于DBA這個講究經驗的工種,這本書就是傳授經驗的,可能對有較多工作經驗的DBA來說,這本書基本沒有什么用,但是,對于剛入職場的新人,或學校里的學生,這本書會有較大的幫助,非常推薦。

MySQL排錯指南

1.4 高性能MySQL

高性能MySQL》是MySQL領域的經典之作,擁有廣泛的影響力,學習MySQL的朋友都應該有所耳聞,所以我就不作過多介紹,唯一的建議就是仔細看、認真看、多看幾遍,我每次看都會有不小的收獲。這就是一本雖然書很厚,但是需要一頁一頁、一行一行都認真看的書。

高性能MySQL

1.5 數據庫索引設計與優化

如果認真學習完前面幾本書,基本上都已經對MySQL掌握得不錯了,但是,如果不了解如何設計一個好的索引,仍然不能成為牛逼的DBA,牛逼的DBA和不牛逼的DBA,一半就是看對索引的掌握情況,《數據庫索引設計與優化》就是從普通DBA走向牛逼DBA的捷徑,這本書在淘寶內部非常推崇,但是在中國名氣卻不是很大,很多人不了解。這本書也是今年夏天剛有中文版本的,非常值得入手以后跟著練習,雖然知道的人不多,豆瓣上也幾乎沒有什么評價,但是,強烈推薦、吐血推薦!

數據庫索引設計與優化

1.6 Effective MySQL系列

Effective MySQL系列》是指:

  • Effective MySQL Replication Techniques in Depth
  • Effective MySQL之SQL語句最優化
  • Effective MySQL之備份與恢復

effective

這一系列并不如前面推薦的好,其中,我只看了前兩本,這幾本書只能算是小冊子,如果有時間可以看看,對某一個”???#8221;進入深入了解。

2.MySQL的源碼

關于MySQL源碼的書非常少,還好現在市面上有兩本不錯的書,而且剛好一本講server層,一本講innodb存儲引擎層,對于學習MySQL源碼會很有幫助,至少能夠更加快速地了解MySQL的原理和宏觀結構,然后再深入細節。此外,還有一些博客或PPT將得也很不錯,這里推薦最好的幾份材料。

2.1 InnoDB - A journey to the core

InnoDB - A journey to the core》 是MySQL大牛Jeremy Cole寫的PPT,介紹InnoDB的存儲???,即表空間、區、段、頁的格式、記錄的格式、槽等等。是學習Innodb存儲的最好的材料。感謝Jeremy Cole!

2.2 深入MySQL源碼

登博的分享《深入MySQL源碼》,相信很多想了解MySQL源碼的朋友已經知道這份PPT,就不過多介紹,不過,要多說一句,登博的參考資料里列出的幾個博客,都要關注一下,干貨滿滿,是學習MySQL必須關注的博客。

2.3 深入理解MySQL核心技術

深入理解MySQL核心技術》是第一本關于MySQL源碼的書,著重介紹了MySQL的Server層,重點介紹了宏觀架構,對于剛開始學習MySQL源碼的人,相信會有很大的幫助,我在學習MySQL源碼的過程中,反復的翻閱了幾遍,這本書剛開始看的時候會很痛苦,但是,對于研究MySQL源碼,非常有幫助,就看你是否需要,如果沒有研究MySQL源碼的決心,這本書應該會被唾棄。

深入理解MySQL核心技術

2.4 MySQL內核:InnoDB存儲引擎

我們組的同事寫的《MySQL內核:InnoDB存儲引擎》,可能宇宙范圍內這本書就數我學得最認真了,雖然書中有很多編輯錯誤,但是,平心而論,還是寫得非常好的,相對于《深入理解MySQL核心技術》,可讀性更強一些,建議研究Innodb存儲引擎的朋友,可以了解一下,先對Innodb有一個宏觀的概念,對大致原理有一個整體的了解,然后再深入細節,肯定會比自己從頭開始研究會快很多,這本書可以幫助你事半功倍。

MySQL內核

2.5 MySQL Internals Manual

MySQL Internals Manual》相對于MySQL Manual來說,寫的太粗糙,誰讓人家是官方文檔呢,研究MySQL源碼的時候可以簡單地參考一下,但是,還是不要指望文檔能夠回答你的問題,還需要看代碼才行。

//dev.mysql.com/doc/internals/en/

2.6 MariaDB原理與實現

評論里提到的《MariaDB原理與實現》我也買了一本,還不錯,MariaDB講的并不多,重點講了Group Commit、線程池和復制的實現,都是MySQL Server層的知識,對MySQL Server層感興趣的可以參考一下。

MariaDB

3. 后記

希望這里推薦的材料對學習MySQL的同學、朋友有所幫助,也歡迎推薦靠譜的學習材料,大家共同進步。



小馬歌 2018-12-03 15:54 發表評論
]]>
java問題排查工具庫(轉) - 棒球比分大小怎么算|网站//www.355548.live/xiaomage234/archive/2018/11/23/433512.html小馬歌小馬歌Fri, 23 Nov 2018 02:47:00 GMT//www.355548.live/xiaomage234/archive/2018/11/23/433512.html//www.355548.live/xiaomage234/comments/433512.html//www.355548.live/xiaomage234/archive/2018/11/23/433512.html#Feedback0//www.355548.live/xiaomage234/comments/commentRss/433512.html//www.355548.live/xiaomage234/services/trackbacks/433512.html閱讀全文

小馬歌 2018-11-23 10:47 發表評論
]]>
孤兒進程與僵尸進程[轉] - 棒球比分大小怎么算|网站//www.355548.live/xiaomage234/archive/2018/09/03/433354.html小馬歌小馬歌Mon, 03 Sep 2018 11:53:00 GMT//www.355548.live/xiaomage234/archive/2018/09/03/433354.html//www.355548.live/xiaomage234/comments/433354.html//www.355548.live/xiaomage234/archive/2018/09/03/433354.html#Feedback0//www.355548.live/xiaomage234/comments/commentRss/433354.html//www.355548.live/xiaomage234/services/trackbacks/433354.html閱讀全文

棒球比分大小怎么算 2018-09-03 19:53 發表評論
]]>
{ganrao}