第20周-2022-05-17

1、總結(jié)tomcat優(yōu)化方法

由于Tomcat的運(yùn)行依賴于JVM嘶卧,從虛擬機(jī)的角度把Tomcat的調(diào)整分為外部環(huán)境調(diào)優(yōu) JVM 和 Tomcat 自身調(diào)優(yōu)兩部分疮胖。

  • 內(nèi)存空間優(yōu)化
    Tomcat的JVM參數(shù)設(shè)置
JAVA_OPTS="-server -Xms4g -Xmx4g -XX:NewSize= -XX:MaxNewSize= "
-server:服務(wù)器模式
-Xms:堆內(nèi)存初始化大小
-Xmx:堆內(nèi)存空間上限(不指定時(shí),大約使用總內(nèi)存的1/4)
-XX:NewSize=:新生代空間初始化大小 
-XX:MaxNewSize=:新生代空間最大值

生產(chǎn)案例:

[root@centos8 ~]#vim /usr/local/tomcat/bin/catalina.sh
JAVA_OPTS="-server -Xms4g -Xmx4g -Xss512k -Xmn1g -
XX:CMSInitiatingOccupancyFraction=65 -XX:+AggressiveOpts -XX:+UseBiasedLocking -
XX:+DisableExplicitGC -XX:MaxTenuringThreshold=10 -XX:NewRatio=2 -
XX:PermSize=128m -XX:MaxPermSize=512m -XX:CMSFullGCsBeforeCompaction=5 -
XX:+ExplicitGCInvokesConcurrent -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -
XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -
XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods"
#一臺tomcat服務(wù)器并發(fā)連接數(shù)不高,生產(chǎn)建議分配物理內(nèi)存通常4G到8G較多,如果需要更多連接,一般會利用虛擬化技術(shù)實(shí)現(xiàn)多臺tomcat
  • 線程池調(diào)整
    常用屬性:
    connectionTimeout :連接超時(shí)時(shí)長,單位ms
    maxThreads:最大線程數(shù)设易,默認(rèn)200
    minSpareThreads:最小空閑線程數(shù)
    maxSpareThreads:最大空閑線程數(shù)
    acceptCount:當(dāng)啟動線程滿了之后逗柴,等待隊(duì)列的最大長度,默認(rèn)100
    URIEncoding:URI 地址編碼格式顿肺,建議使用 UTF-8
    enableLookups:是否啟用客戶端主機(jī)名的DNS反向解析戏溺,缺省禁用,建議禁用屠尊,就使用客戶端IP就行
    compression:是否啟用傳輸壓縮機(jī)制于购,建議 "on",CPU和流量的平衡
    • compressionMinSize:啟用壓縮傳輸?shù)臄?shù)據(jù)流最小值知染,單位是字節(jié)
    • compressableMimeType:定義啟用壓縮功能的MIME類型text/html, text/xml, text/css,text/javascript
      示例:
[root@centos8 ~]#vim /usr/local/tomcat/conf/server.xml
......
<Connector port="8080" protocol="HTTP/1.1"  connectionTimeout="20000" redirectPort="8443" />
......

2肋僧、java程序出現(xiàn)oom如何解決?什么場景下會出現(xiàn)oom控淡?

當(dāng)JVM因?yàn)闆]有足夠內(nèi)存來為對象分配空間嫌吠,并且垃圾回收器也沒有空間可回收時(shí),系統(tǒng)會出現(xiàn)如下OOM日志:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
 at java.util.Arrays.copyOf(Arrays.java:3332)
 at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
 at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:674)
 at java.lang.StringBuilder.append(StringBuilder.java:208)
 at HeapOom2.main(HeapOom2.java:6)

通常出現(xiàn)OOM的原因是:

  • 給應(yīng)用分配的內(nèi)存太少掺炭,一般是啟動時(shí)的JVM參數(shù)指定太少
  • 應(yīng)用使用太多辫诅,并且用完沒有釋放,此時(shí)就會造成內(nèi)存泄漏或內(nèi)存溢出
    • 可以通過JDK工具來分析原因涧狮,如jvisualvm配合Visual GC插件炕矮;或通過商業(yè)軟件profiler定位出現(xiàn)問題的代碼

解決思路:

  • 限制java進(jìn)程的max heap,并且降低java程序的worker數(shù)量者冤,從而降低內(nèi)存使用
  • 給系統(tǒng)增加swap空間
  • 設(shè)置內(nèi)核參數(shù)肤视,不允許內(nèi)存申請過量,不推薦的做法涉枫;
  • linux默認(rèn)是允許內(nèi)存申請過量的邢滑,系統(tǒng)寄希望于實(shí)際上用不到那么多內(nèi)存,但如果出現(xiàn)內(nèi)存過量時(shí):
    linux通過OOM killer機(jī)制愿汰,挑選一個進(jìn)程kill來騰出部分內(nèi)存困后,還不夠那就繼續(xù)kill,也可以通過vm.panic_on_oom衬廷,當(dāng)發(fā)生OOM時(shí)就自動重啟系統(tǒng)摇予,重啟和kill都可能造成業(yè)務(wù)中斷,linux 2.6之后吗跋,允許通過vm.overcommit_memory內(nèi)核參數(shù)來禁止memory overcommit

3侧戴、簡述redis特點(diǎn)及其應(yīng)用場景

redis特點(diǎn):

  • 速度快: 10W QPS,基于內(nèi)存,C語言實(shí)現(xiàn)
  • 單線程
  • 持久化
  • 支持多種數(shù)據(jù)結(jié)構(gòu)
  • 支持多種編程語言
  • 功能豐富: 支持Lua腳本,發(fā)布訂閱,事務(wù),pipeline等功能
  • 簡單: 代碼短小精悍(單機(jī)核心代碼只有23000行左右),單線程開發(fā)容易,不依賴外部庫,使用簡單
  • 主從復(fù)制
  • 支持高可用和分布式

redis應(yīng)用場景:

  • Session 共享:常見于web集群中的Tomcat或者PHP中多web服務(wù)器session共享
  • 緩存:數(shù)據(jù)查詢、電商網(wǎng)站商品信息、新聞內(nèi)容
  • 計(jì)數(shù)器:訪問排行榜救鲤、商品瀏覽數(shù)等和次數(shù)相關(guān)的數(shù)值統(tǒng)計(jì)場景
  • 微博/微信社交場合:共同好友,粉絲數(shù),關(guān)注,點(diǎn)贊評論等
  • 消息隊(duì)列:ELK的日志緩存久窟、部分業(yè)務(wù)的訂閱發(fā)布系統(tǒng)
  • 地理位置: 基于GEO(地理信息定位),實(shí)現(xiàn)搖一搖,附近的人,外賣等功能

4、對比redis的RDB本缠、AOF模式的優(yōu)缺點(diǎn)

  • RDB對內(nèi)存執(zhí)行快照斥扛,保存了某個時(shí)間點(diǎn)內(nèi)存中的所有數(shù)據(jù),當(dāng)出現(xiàn)問題時(shí)可以恢復(fù)到不同時(shí)間點(diǎn)的版本丹锹;但RDB不能實(shí)時(shí)保存數(shù)據(jù)稀颁,會丟失故障時(shí)到上一個時(shí)間點(diǎn)之間未保存的數(shù)據(jù);
  • RDB是通過父進(jìn)程fork的子進(jìn)程來執(zhí)行的保存工作楣黍;但如果子進(jìn)程在存在期間匾灶,發(fā)生了大量的寫操作,會導(dǎo)致子進(jìn)程執(zhí)行復(fù)制操作租漂,就會出現(xiàn)很多的page-fault阶女,這樣需要消耗不少性能在復(fù)制上
  • AOF的數(shù)據(jù)安全性相對較高,根據(jù)使用的fsync策略(何時(shí)同步內(nèi)存數(shù)據(jù)到磁盤)哩治,默認(rèn)是1s同步一次秃踩,就算發(fā)生故障,也只會丟失1s內(nèi)的數(shù)據(jù)业筏;但根據(jù)fsync的策略不同憔杨,aof可能速度慢于rdb
  • AOF會產(chǎn)生重復(fù)記錄,比如對一個數(shù)據(jù)執(zhí)行了創(chuàng)建和修改蒜胖,則創(chuàng)建和修改兩個操作都會被記錄消别;
  • AOF在恢復(fù)大數(shù)據(jù)集時(shí)需要比RDB久的時(shí)間,因?yàn)镽DB是直接加載到內(nèi)存台谢,而AOF則需要一條條執(zhí)行操作寻狂;

5、實(shí)現(xiàn)redis哨兵对碌,模擬master故障場景

環(huán)境:
初始master節(jié)點(diǎn):192.168.184.101
初始slave1節(jié)點(diǎn):192.168.184.102
初始slave2節(jié)點(diǎn):192.168.184.103

使用腳本安裝所有redis

[root@centos7-01 ~]# cat install_redis.sh 
#!/bin/bash

. /etc/init.d/functions 
VERSION=redis-6.2.4
PASSWORD=123456
INSTALL_DIR=/apps/redis

install() {
yum  -y install gcc jemalloc-devel || { action "安裝軟件包失敗荆虱,請檢查網(wǎng)絡(luò)配置" false ; exit; }

wget http://download.redis.io/releases/${VERSION}.tar.gz || { action "Redis 源碼下載失敗" false ; exit; }



tar xf ${VERSION}.tar.gz
cd ${VERSION}
make -j 4 PREFIX=${INSTALL_DIR} install && action "Redis 編譯安裝完成" || { action "Redis 編譯安裝失敗" false ;exit ; }


ln -s ${INSTALL_DIR}/bin/redis-*  /usr/bin/
mkdir -p ${INSTALL_DIR}/{etc,log,data,run}
cp redis.conf  ${INSTALL_DIR}/etc/

sed -i -e 's/bind 127.0.0.1/bind 0.0.0.0/'  -e "/# requirepass/a requirepass $PASSWORD"  -e "/^dir .*/c dir ${INSTALL_DIR}/data/"  -e "/logfile .*/c logfile ${INSTALL_DIR}/log/redis-6379.log"  -e  "/^pidfile .*/c  pidfile ${INSTALL_DIR}/run/redis_6379.pid" ${INSTALL_DIR}/etc/redis.conf


if id redis &> /dev/null ;then 
    action "Redis 用戶已存在" false  
else
    useradd -r -s /sbin/nologin redis
    action "Redis 用戶創(chuàng)建成功"
fi

chown -R redis.redis ${INSTALL_DIR}

cat >> /etc/sysctl.conf <<EOF
net.core.somaxconn = 1024
vm.overcommit_memory = 1
EOF
sysctl -p 

echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local
/etc/rc.d/rc.local

cat > /usr/lib/systemd/system/redis.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target

[Service]
ExecStart=${INSTALL_DIR}/bin/redis-server ${INSTALL_DIR}/etc/redis.conf --supervised systemd
ExecStop=/bin/kill -s QUIT \$MAINPID
#Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target

EOF
systemctl daemon-reload 
systemctl enable --now  redis &> /dev/null && action "Redis 服務(wù)啟動成功,Redis信息如下:" || { action "Redis 啟動失敗" false ;exit; } 

redis-cli -a $PASSWORD INFO Server 2> /dev/null

}

install

在所有主從節(jié)點(diǎn)配置

[root@centos7-01 ~]# vi /apps/redis/etc/redis.conf
bind 0.0.0.0
masterauth 123456
requirepass 123456

在所有從節(jié)點(diǎn)配置

[root@centos7-02 ~]# echo "replicaof 192.168.184.101 6379" >> /apps/redis/etc/redis.conf 
[root@centos7-02 ~]# systemctl restart redis

測試主從復(fù)制

#查看master狀態(tài)
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.184.102,port=6379,state=online,offset=351,lag=1
slave1:ip=192.168.184.103,port=6379,state=online,offset=351,lag=1
master_failover_state:no-failover
master_replid:6a5cf39edbeb45dd6b91eaa3cedcaf55bff50674
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:351
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:351

#在master寫數(shù)據(jù)
[root@centos7-01 ~]# redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> set name test1
OK

#在slave查看數(shù)據(jù)
[root@centos7-02 ~]# redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> get name
"test1"

配置哨兵
所有redis節(jié)點(diǎn)使用相同的以下示例的配置文件

[root@centos7-01 ~]# grep -vE '^#|^$' /apps/redis/etc/redis-sentinel.conf 
bind 0.0.0.0
port 26379
daemonize yes
pidfile /apps/redis/run/redis-sentinel.pid
logfile "/apps/redis/log/sentinel_26379.log"
dir /tmp
sentinel monitor mymaster 192.168.184.101 6379 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 3000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes

將配置文件復(fù)制到slave節(jié)點(diǎn)
[root@centos7-01 ~]# scp /apps/redis/etc/redis-sentinel.conf 192.168.184.102:/apps/redis/etc/
[root@centos7-01 ~]# scp /apps/redis/etc/redis-sentinel.conf 192.168.184.103:/apps/redis/etc/

在所有節(jié)點(diǎn)生成新的service文件

[root@centos7-01 ~]# cat /lib/systemd/system/redis-sentinel.service 
[Unit]
Description=Redis Sentinel
After=network.target

[Service]
ExecStart=/apps/redis/bin/redis-sentinel /apps/redis/etc/redis-sentinel.conf --supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
User=redis
Group=redis
Type=notify
RuntimeDirectory=redis
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target

所有節(jié)點(diǎn)配置目錄權(quán)限,啟動sentinel

[root@centos7-01 ~]# chown -R redis.redis /apps/redis/
[root@centos7-01 ~]# systemctl daemon-reload
[root@centos7-01 ~]# systemctl enable --now redis-sentinel

查看sentinel狀態(tài)

[root@centos7-01 ~]# redis-cli -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.184.101:6379,slaves=2,sentinels=3

模擬101master節(jié)點(diǎn)故障

[root@centos7-01 ~]# redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> shutdown
not connected> 

102slave已提升為主節(jié)點(diǎn)

#查看slave節(jié)點(diǎn)日志
[root@centos7-01 ~]# tail -f /apps/redis/log/sentinel_26379.log
31252:X 18 May 2022 08:07:13.148 # +sdown master mymaster 192.168.184.101 6379
31252:X 18 May 2022 08:07:13.177 # +new-epoch 1
31252:X 18 May 2022 08:07:13.178 # +vote-for-leader d8410373cb35a36984fb25a19c236f16c3d6e74d 1
31252:X 18 May 2022 08:07:13.240 # +odown master mymaster 192.168.184.101 6379 #quorum 3/2
31252:X 18 May 2022 08:07:13.240 # Next failover delay: I will not start a failover before Wed May 18 08:13:13 2022
31252:X 18 May 2022 08:07:14.289 # +config-update-from sentinel d8410373cb35a36984fb25a19c236f16c3d6e74d 192.168.184.103 26379 @ mymaster 192.168.184.101 6379
31252:X 18 May 2022 08:07:14.289 # +switch-master mymaster 192.168.184.101 6379 192.168.184.102 6379
31252:X 18 May 2022 08:07:14.290 * +slave slave 192.168.184.103:6379 192.168.184.103 6379 @ mymaster 192.168.184.102 6379
31252:X 18 May 2022 08:07:14.290 * +slave slave 192.168.184.101:6379 192.168.184.101 6379 @ mymaster 192.168.184.102 6379
31252:X 18 May 2022 08:07:17.291 # +sdown slave 192.168.184.101:6379 192.168.184.101 6379 @ mymaster 192.168.184.102 6379

# 查看102slave節(jié)點(diǎn)狀態(tài)
[root@centos7-02 ~]# redis-cli -a 123456 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.184.103,port=6379,state=online,offset=130524,lag=1
master_failover_state:no-failover
master_replid:7103af6186691a2d95490d649ce39ac48203caf6
master_replid2:6a5cf39edbeb45dd6b91eaa3cedcaf55bff50674
master_repl_offset:130669
second_repl_offset:92695
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:130669

#查看102slave節(jié)點(diǎn)sentinel狀態(tài)
[root@centos7-02 ~]# redis-cli -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.184.102:6379,slaves=2,sentinels=3

恢復(fù)101redis

[root@centos7-01 ~]# systemctl start redis
[root@centos7-01 ~]# redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.184.102
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:195382
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:7103af6186691a2d95490d649ce39ac48203caf6
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:195382
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:191417
repl_backlog_histlen:3966
#原master節(jié)點(diǎn)恢復(fù)后狀態(tài)為slave
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末朽们,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子诉位,更是在濱河造成了極大的恐慌骑脱,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件苍糠,死亡現(xiàn)場離奇詭異叁丧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進(jìn)店門拥娄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蚊锹,“玉大人,你說我怎么就攤上這事稚瘾∧道ィ” “怎么了?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵摊欠,是天一觀的道長丢烘。 經(jīng)常有香客問我,道長些椒,這世上最難降的妖魔是什么播瞳? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮免糕,結(jié)果婚禮上赢乓,老公的妹妹穿的比我還像新娘。我一直安慰自己石窑,他們只是感情好骏全,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著尼斧,像睡著了一般姜贡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上棺棵,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天楼咳,我揣著相機(jī)與錄音,去河邊找鬼烛恤。 笑死母怜,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缚柏。 我是一名探鬼主播苹熏,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼币喧!你這毒婦竟也來了轨域?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤杀餐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后史翘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冀续,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡必峰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年洪唐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吼蚁。...
    茶點(diǎn)故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖桂敛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情术唬,我是刑警寧澤薪伏,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站粗仓,受9級特大地震影響嫁怀,放射性物質(zhì)發(fā)生泄漏借浊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一存捺、第九天 我趴在偏房一處隱蔽的房頂上張望曙蒸。 院中可真熱鬧,春花似錦纽窟、人聲如沸肖油。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽县袱。三九已至瓷胧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間搓萧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工揍移, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留反肋,地道東北人。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓双谆,卻偏偏與公主長得像呢簸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內(nèi)容