RHEL / CentOS 7 安裝 NFS Server

NFS Server 安裝
安裝 NFS:
# yum install nfs-utils nfs-utils-lib

設定分享的目錄, 以下是 /var/nfsshare:
# mkdir /var/nfsshare
# chmod -R 777 /var/nfsshare/

開啟 /etc/exports 檔案, 加入以下內容:
/var/nfsshare 192.168.0.11(rw,sync,no_root_squash,no_all_squash)

啟動 NFS Server, 設定開機自動執行及在 firewalld 開放 NFS:
# systemctl enable rpcbind
# systemctl enable nfs-server
# systemctl enable nfs-lock
# systemctl enable nfs-idmap
# systemctl start rpcbind
# systemctl start nfs-server
# systemctl start nfs-lock
# systemctl start nfs-idmap
# firewall-cmd –permanent –zone=public –add-service=nfs
# firewall-cmd –permanent –zone=public –add-service=rpc-bind
# firewall-cmd –reload

NFS Client 安裝
# yum install nfs-utils

建立 NFS 目錄掛載點:
mkdir -p /mnt/nfs/var/nfsshare

現在可以用 mount 指令掛載 192.168.0.10 分享出來的目錄:
# mount -t nfs 192.168.0.10:/var/nfsshare /mnt/nfs/var/nfsshare/

如果需要下次重新開機後就會自動掛載, 現在開啟 /etc/fstab, 加入以下內容:
192.168.0.10:/var/nfsshare /mnt/nfs/var/nfsshare nfs defaults 0 0

留意上面的 192.168.0.10 是 NFS Server 的 IP, 需要根據自己的情況修改。

—–

Fix the problem CentOS 7 won’t auto-mount NFS on boot

Append text to the end of /usr/lib/systemd/system/nfs-idmap.service

[Install]
WantedBy=multi-user.target

Append text to the end of /usr/lib/systemd/system/nfs-lock.service

[Install]
WantedBy=nfs.target

Enable related services

systemctl enable nfs-idmapd.service 
systemctl enable rpc-statd.service 

systemctl enable rpcbind.socket

systemctl status nfs-idmapd.service -l
systemctl status rpc-statd.service –l

Then restarted the OS, I got it.

shutdown -r now

Check whether mount works

systemctl start rpcbind
systemctl enable rpcbind
mount -a

===================

建置 NFS Server 有三個重點組態檔:
/etc/exports
/etc/hosts.allow
/etc/hosts.deny

通常編輯 /etc/exports 就能讓 NFS 運作。

當一個 request 進來,伺服器會依序這樣作:
一、首先檢查是不是 hosts.allow 裡列的client,如果是就允許存取,如果不是就到下一個檢查。
二、接著檢查是不是 hosts.deny 裡列的client,如果是就拒絕存取,如果不是就到下一個檢查。
三、若這個 client 不在 hosts.allow 也不在 hosts.deny,那就允許這個 client 存取。

//————————————————
(安裝 NFS 套件)
apt-get update &&
apt-get install nfs-kernel-server

=>修改 /etc/default/portmap
確認 -i 127.0.0.1 是註解掉的

(禁止主機和伺服器進行NFS連接)
=>修改 /etc/hosts.deny
——————————
ALL:ALL
——————————
portmap:ALL
lockd:ALL
mountd:ALL
rquotad:ALL
statd:ALL
——————————

(允許主機和伺服器進行NFS連接)
=>修改 /etc/hosts.allow
——————————
portmap:ALL
lockd:ALL
mountd:ALL
rquotad:ALL
statd:ALL
——————————
portmap: 192.168.0.
lockd:   192.168.0.
rquotad: 192.168.0.
mountd:  192.168.0.
statd:   192.168.0.
——————————

(NFS掛載目錄及權限)
=>修改 /etc/exports
——————————
/home/sw/open_fd *(rw,sync,no_root_squash)
/home/sw/share_folder 192.168.0.*(rw,sync,no_root_squash)
——————————
更新
sudo exportfs -ra
sudo /etc/init.d/nfs-kernel-server restart

權限方面常見的參數(小括號內的參數):
rw:read-write,可讀寫的權限。
ro:read-only,唯讀的權限。
sync:資料同步寫入到記憶體與硬碟當中。
async:資料會先暫存於記憶體當中,而非直接寫入硬碟。
no_root_squash:登入 NFS 的使用者,如果是 root 時,對於這個分享的目錄來說,使用者具有 root 的權限。
root_squash:登入 NFS 的使用者,如果是 root 時,對於這個分享的目錄來說,使用者的權限都會被壓縮成為匿名使用者。
all_squash:不論登入 NFS 的使用者身份為何,使用者的權限都會被壓縮成為匿名使用者。

(檢查配置)
showmount -e NFS-SERVER-IP
(e.g)
showmount -e 192.168.13.5

(掛載遠端目錄)
mount -t nfs NFS-SERVER-IP:SHARE-PATH-FD MOUNT
mount -F nfs [-o mount-options] server:/directory /mount-point
(e.g)
mount -t nfs 192.168.13.15:/home/sw/open_fd /mnt

===================

Reference URL:

https://www.phpini.com/linux/rhel-centos-7-install-nfs-server

https://unix.stackexchange.com/questions/211688/cannot-start-nfs-in-centos-7-failed-to-issue-method-call-no-such-file-or-direc

http://welkinchen.pixnet.net/blog/post/5251478-ubuntu-nfs-連線

https://dywang.csie.cyut.edu.tw/dywang/rhce7/node61.html

廣告

Git restricted shell script

1. The better way:

# create git user
sudo adduser git
su git
cd
## configure ssh
mkdir .ssh && chmod 700 .ssh
touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys
## append ssh public keys from your team members
cat /tmp/id_rsa.yours.pub >> ~/.ssh/authorized_keys
cat /tmp/id_rsa.others.pub >> ~/.ssh/authorized_keys

# restrict ssh access
cat /etc/shells   # see if `git-shell` is already in there.  If not…
which git-shell   # make sure git-shell is installed on your system.
sudo nano /etc/shells  # and add the path to git-shell from last command

sudo chsh git  # and enter the path to git-shell, usually: /usr/bin/git-shell

# create git repo
git init –bare project.git

Reference URL: http://blog.airobot.org/2016/10/09/搭建简易git私服/

 

2. The brute force way:

Put below restrict in the ~/.ssh/authorized_keys file:
command="/path/to/git_rsh.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAAB3….o9M9qz4xqGCqGXoJw= user@host

The git_rsh.sh script:
#!/bin/sh

if [ $# -ne 2 ] || [ “$1″ != “-c" ] ; then
printf “interactive login not permitted\n"
exit 1
fi

set — $2

if [ $# != 2 ] ; then
printf “wrong number of arguments\n"
exit 1
fi

case “$1″ in
( git-upload-pack | git-receive-pack )
;; # continue execution
( * )
printf “command not allowed\n"
exit 1
;;
esac

# Canonicalize the path name: we don’t want escape out of
# git via ../ path components.

gitpath=$(readlink -f “$2″) # GNU Coreutils specific

case “$gitpath" in
( /git/* )
;; # continue execution
( * )
printf “access denied outside of /git\n"
exit 1
;;
esac

if ! [ -e “$gitpath" ] ; then
printf “that git repo doesn’t exist\n"
exit 1
fi

“$1″ “$gitpath"

Reference URL: https://stackoverflow.com/questions/402615/how-to-restrict-ssh-users-to-a-predefined-set-of-commands-after-login

CentOS 7 安裝 Python3,pip3

CentOS 7 默認安裝了 Python 2,當需要使用 Python 3 的時候,可以手動下載 Python 源碼後編譯安裝。

一,安裝 Python 3

1.1 安裝準備

$ sudo mkdir/usr/local/python3 #創建安裝目錄
#下載Python源文件
#注意:wget獲取https的時候要加上: – no-check-certificate
$ tar -xzvf Python-3.6.0.tgz #解壓縮包
$ cd Python-3.6.0 #進入解壓目錄

1.2 編譯安裝

$ sudo ./configure –prefix = /usr/local/python3 #指定創建的目錄
$ sudo make
$ sudo make install

1.3 配置

1.3.1 兩個版本共存

創建 python3 的軟鏈接:

$ sudo ln -s /usr/local/python3/bin/python3 /usr/bin/python3

這樣就可以通過python命令使用 Python 2, python3來使用 Python 3。

1.3.2 修改默認為 Python 3

/usr/bin中的python備份

 $ sudo mv python python.bak

然後創建 python3 的軟鏈接

 $ sudo ln -s /usr/local/python3/bin/python3 /usr/bin/python

這樣默認的 Python 版本就替換為 Python 3 了。

因為 yum 使用 Python 2,因此替換為 Python 3 後可能無法正常工作,因此修改 yum 配置文件

sudo vi /usr/bin/yum

將第一行指定的 python 版本改為 python2.7( #!/usr/bin/python改為#!/usr/bin/python2.7 )

二,安裝 pip

2.1 yum 安裝

#首先安裝epel擴展源
$ sudo yum -y安裝epel-release
#安裝python-pip
$ sudo yum -y安裝python-pip
#清除緩存
$ sudo yum清理所有

通過這種方式貌似只能安裝 pip2,想要安裝 Python 3 的 pip,可以通過以下的源代碼安裝方式。

2.2 源碼安裝

#下載源代碼
$ wget –no-check-certificate https://github.com/pypa/pip/archive/9.0.1.tar.gz
$ tar -zvxf 9.0.1 -C pip-9.0.1 #解壓文件
$ cd pip-9.0.1
#使用Python 3安裝
$ python3 setup.py install

創建鏈接:

$ sudo ln -s /usr/local/python3/bin/pip /usr/bin/pip3

2.3 升級點

$ pip install –upgrade pip

參考文章

https://ehlxr.me/2017/01/07/CentOS-7-%E5%AE%89%E8%A3%85-Python3%E3%80%81pip3/

Spring Cloud學習資源

Spring Cloud中文網:
https://springcloud.cc
https://springcloud.cc/spring-cloud-dalston.html

Spring Boot參考指南:
https://www.gitbook.com/book/qbgbook/spring-boot-reference-guide-zh/
https://qbgbook.gitbooks.io/spring-boot-reference-guide-zh/

Spring Cloud Stream Reference:
http://docs.spring.io/spring-cloud-stream/docs/Chelsea.SR2/reference/htmlsingle/
http://weifuwu.io/2016/09/15/dive-into-spring-cloud-stream/

Spring Cloud Task Reference:
http://docs.spring.io/spring-cloud-task/docs/1.2.0.RELEASE/reference/htmlsingle/

[轉] 軟體工程

文章轉錄自:http://irw.ncut.edu.tw/peterju/se.html

物件導向的塑模 = 軟體架構

軟體開發如同音樂譜曲及建築設計,其過程中必須將需求、分析、設計、實作、佈署等各項工作流程之不同觀點予以呈現,這就是軟體系統之塑模(Modeling)。

Booch等人 / Rational Software 提出可從4+1觀點(4+1 view)來看軟體系統架構(凸顯使用個案的重要性)

  • 使用個案觀點(Use Case View):以使用個案充分表達軟體功能需求
  • 設計觀點(Design View):以物件的觀念,表達出軟體設計結果 (Logical View)
  • 流程觀點(Process View):
  • 實施觀點(Implementation View)
  • 佈署觀點(Deployment View)

根據上述5個觀點我們可以整理出6種塑模

  • 使用個案塑模:使用個案圖
  • 物件資料結構塑模:類別圖、物件圖
  • 物件互動行為塑模:互動圖(包含了循序圖、合作圖)
  • 作業行為塑模:活動圖、狀態圖
  • 使用者介面塑模:
  • 系統元件與組織結構塑模:元件圖、部署圖

物件導向的軟體維護

  • 軟體的維護就是軟體的再生,維護較開發而言要花更多的金錢與時間
  • 軟體維護的思維上就是要考慮到 可維護性(Maintainability) 可重複使用性(Reuseability)
  • 傳統的重複使用方案並無法兼顧可維護性與可重複使用性的目標,物件導向設計的重複使用方式可在含有宏觀商業邏輯的抽象層次的上層結構來考量,以達到可維護與可重複使用的目標。
  • 物件導向類別設計的法則
    • 開閉原則(Open-Closed Principle ; OCP)
    • Liskov代換原則(Liskov Substitution Principle ; LSP)
    • 依賴倒轉原則(Dependency Inversion Principle ; DIP)
    • 介面隔離原則(Interface Segregation Principle ; ISP)
    • 組合/聚合重複使用原則(Composition / Aggregation Principle ; CARP)
    • Demeter原則(Law of Demeter; LoD)

開閉原則(Open-Closed Principle ; OCP)

  • 模組應當敞開擴充大門,但關閉修改之窗
  • 如何達成開閉原則,關鍵在抽象化。
  • 不允許更改的是系統的抽象層,允許擴充的是系統的實作層。
  • OCP的另一個角度是EVP對可變性的封裝原則(Principle of Encapsulation of Variation)即找到一個系統的可變因素,並將之封裝起來。
  • 可變性必須被封裝,那不同的可變性呢?應用繼承來處理,因此繼承應被視為封裝變化的方法,但繼承的層數避免超過2層以免不同的可變性混和。
  • 應避免將單純的流程控制轉移語句改寫成多型,除非內含了某種商務邏輯。
  • 所有的設計樣式(Design Pattern)都是針對不同的可變性封裝,使系統在不同的角度上達到開閉原則。

Liskov代換原則(Liskov Substitution Principle; LSP)

  • 子類別應該可以使用其基礎類別替代
  • Liskov代換原則是繼承之所以能重複使用的基石,只有當衍生類別可以替換掉基礎類別,且軟體的功能不受影響時,其類別才算真正的被重複使用,而衍生類別也才能夠在基礎類別的基礎上增加新的行為。
  • Liskov代換原則要求凡是基礎類別使用的地方,衍生類別一定適用,故衍生類別必須包含全部基礎類別的介面
  • 針對違反LSP設計時可行的重構(Refactoring)方式
    • 當類別A錯誤的繼承類別B時,可建構一個新的抽象類別C,作為2個具體類別A,B的父類別
    • 當類別A錯誤的繼承類別B時,可重構為類別B委派(Delegate)類別A

依賴倒轉原則(Dependency Inversion Principle; DIP)

  • 要依賴於抽象,而不要依賴於具體
  • 依賴倒轉原則的策略是依賴介面或抽象方法及類別,而不是具體方法或類別,包括了下列情況都得遵循DIP
    • 變數的類別宣告
    • 參數的類別宣告
    • 方法的傳回型態宣告
    • 型態的轉換
  • 抽象層級含有宏觀和重要的商務邏輯,具體層級含有與實作有關的演算法語次要的商業邏輯,而傳統的程序性設計或錯誤的類別規劃會讓抽象層級依賴於具體層級,因此依賴倒轉原則可倒轉此一現象,讓實作改變時,商業邏輯無須變動。
  • 一個具體Java類別應當只實作Java介面和抽象Java類別中宣告的方法,而不應當給出多餘的方法。
  • 若Java程式要參照一個物件,若此物件有一個抽象型態,則應使用此抽象型態作為靜態型態(Static Type)
    • 靜態型態(Static Type) = 實際型態(Apparent Type):變數被宣告時的類別
    • 實際型態(Actual Type):變數所參照的物件真實型態
  • 若一個物件存在其抽象類別,就應當在任何參照此物件的地方使用抽象類別
  • Java語言中建構一個物件的程式是違背OCP與DIP的,但可在此類別被建構出來後過多型性使得使用端依賴於其抽象類別。
    • List employees = new Vector();
  • DIP是最難實作的原則,因為會使用到物件工廠就會產生大量的類別。
  • DIP假定所有的具體類別都是會變化的並不完全正確,因為某些具體類別是相當的穩定因此並不需要為此發明一個抽象型態。

介面隔離原則(Interface Segregation Principle; ISP)

  • 由客戶端指定的許多介面比一個一般用途的介面好。
  • 使用多個專門的介面比使用單一的總介面要好,否則會造成對介面的污染(Interface Contamination)。
  • 一個類別對另一個類別的依賴性應當是建立在最小的介面上的。

組合/聚合重複使用原則(Composition / AggregationPrinciple ; CARP)

Demeter原則(Law of Demeter; LoD)

統一塑模語言(Unified Modeling Language ; UML)

  • 由Rational software corporation融合了物件導向三劍客的方法論,統一了以物件導向分析與設計的表示法,於1997年11月由 OMG(Object Management Group) 公布為物件導向視覺化塑模的標準,目前 最新的版本為 2.0 (2003/06/01)
  • UML是一種塑模語言,而非方法論,它並沒有規範符號的使用時機與次序僅利用符號來達到溝通的目的,從分析,設計到實作都可以使用同一套符號來表達,因此應用時可以搭配適合的方法論。
  • UML之所以重要,就是因為他有助於軟體開發人員之間的溝通。我們必須在某種程度上使用他以協助溝通,而非阻礙溝通。
  • 循序圖、合作圖合稱互動圖。
  • UML設計的理念
    • 使用個案導向(強調以使用者的角度來定義功能需求)
    • 軟體架構設計(強調系統開發要有藍圖)
    • 往覆,漸增式流程(強調降低專案風險)

使用個案圖(Use Case Diagram)

  • 以OO技術開發系統時在需求分析時常利用典型的情節(Scenario)來進行需求塑模,這種個案模式一直沒有統一的表達方式直到Ivar Jacobson等人(1996) 才將使用個案的表達正式化。
  • 使用個案圖表示從使用者之觀點描述系統的行為者與系統間之互動行為與關係,包含了行為者和使用個案二個元件,此法在資料與展示格式上僅利用文字描述,若能搭配結構化中的藍圖與資料詞彙則可補強其不足之處。
  • 使用案例是專業分工的依據,是專案進度評量的重要因素。

行為者(Actor) = 參與者

  • 環境中與系統有互動關係的人或事物,有該使用個案的啟動者即 主要行為者(Primary Actor) 與其他參與者即 次要行為者(Secondary Actor)
  • 參與者被繪製成一個火柴棒形狀的小人並將名稱置其下方。

使用個案(Use Case)

  • 使用者透過介面要求系統所做一系列相關的事件流,包含了最主要的事件即 基本路徑(Basic Course) 與其他衍生事件或可能發生的錯誤即 替代路徑(Alternative Courses)
  • 使用案例被繪製成橢圓形並將名稱置於圖形內部或底部來表示
  • 使用個案間的關係:
    • 關聯(association):使用個案與行為者之間的關係,以實線段表示。
    • 包含(Include):一個使用個案會用到另一個使用個案,二個或以上的使用個案具有相同的行為模式時,可將該段行為模式獨立出來成為一個新的使用個案,再建立包含的關係,用一個虛線實心箭頭的線段並含有關鍵字 <<include>> 。
    • 延伸(Extend):在某情況下,使用個案會插入另一使用個案的定義中,用一個虛線實心箭頭的線段並含有關鍵字 <<extend>> 。
    • 一般化(Generalization):一個使用個案繼承另一個使用個案的行為, 用一個實線空心箭頭表示的線段從子使用個案指向父使用個案,且箭頭朝向父使用個案端。

情節(Scenario)

使用個案中的某一個單一執行路徑,可能是基本路徑也可能是替代路徑。

建構使用個案圖的步驟

  1. 找出行為者:從環境圖找
  2. 找出使用個案:由行為者找出使用個案
  3. 描述使用個案:可用自然語言或事件條列式
  4. 找出使用個案間的關係:
  5. 繪製使用個案圖

類別圖(Class Diagram)

  • 表示系統存在之類別、介面及它們間之靜態資料結構與邏輯關係
  • 通常以三層表示
    • 類別名:正體字:具體類別,斜體字:抽象類別,介面:<interface>
    • 屬性層:
    • 方法層:
  • 屬性與方法有四種封裝方式
    • public:以符號 + 表示
    • private:以符號 表示
    • protected:以符號 # 表示
    • static:以符號 _ 表示
  • 描述介面的類別圖:沒有private的封裝
  • 描述物件的類別圖:描述類別的實體,名稱下需加底線

關係

類別間的關係包括了

  • 依賴 / 相依(Dependency)
    • 使用的關係,表達一個類別會用到另一個類別
    • 另一個類別的改變會影響到使用他的類別,但反之不必然
    • 一類別的區域變數,方法參數,方法返回值,對靜態方法呼叫時是另一個類別時稱之
    • 以虛線開箭頭表示。——->
  • 一般化(Generalization)
    • 繼承的關係,包括了類別間的繼承,介面間的繼承,類別對介面的實作等
    • 以實線空心箭頭表示。
  • 關聯/結合(Association)
    • 同一層級的類別間靜態的結構關係
    • Java語言中是使用實體屬性實作的
    • 其關係有雙向與單向,建議多用單向
    • 關係有基數(Multiplicity),關係有名稱,但通常均予以省略
    • 以實線段表示。 —
      • 依關聯的類別個數來分
        • 二元關聯(Binary Association)
        • 多元關聯(n-ary Association)
      • 依描述整體與部分的關係來分(不同層級的類別)
        • 聚合 / 聚集(Aggregation):以實線且整體端加一個空心的菱形表示。◇—
        • 合成 / 組合(Composition):整體物件需負責部分物件的生命週期,以實線且整體端加一個實心的菱形表示。◆—
  • 實現化(Realization)
    • 以介面實現其他類別之描述
    • 以虛線空心箭頭表示。

基數(Multiplicity) =多重性

在類別連線上與類別之旁以數字標示與之關聯的數量。

物件圖(Object Diagram)

  • 描述系統於某一時間點的靜態結構,也稱為案例圖,包含了物件與連線二個元件。物件間的關係稱為連線(Link)。

循序圖(Sequence Diagram)

  • 以時間發生之先後順序來表達物件間的訊息傳遞與處理之程序,包含了類別之物件、訊息、操作、生命線與控制焦點等元件。
  • 循序圖有2個象線
    • 垂直象線依照訊息呼叫發生的時間順序,來描述訊息呼叫的先後次序。
    • 水平象線描述一個物件實體傳送訊息給哪一個物件實體。

訊息(Message) =刺激(Stimuli)

由某一物件傳送訊息至另一物件以啟動操作,以上下位置表示順序。

生命線(Lifeline)

表達物件再某時段的存在,以物件下與物件垂直之虛線表示。

控制焦點 (Focus of Control) =啟動條(ActivationBar)

表達物件執行某動作之時段,與生命線重疊且以高瘦的矩形表示。

系統邊界 (System Border)

系統與外界溝通之介面,通常放置在循序圖的最左側。

建構循序圖的步驟

  1. 確認物件
  2. 描述操作
  3. 描述訊息
  4. 繪製循序圖

合作圖(Collaboration Diagram)

  • 著重表達物件間之連結結構,並能同時展現物件間的訊息傳遞與處理之程序,包含了類別之物件、連結、訊息與操作等元件。
  • Rational Rose可將循序圖直接轉換成合作圖。
  • 合作圖與循序圖相比較,少了物件生命線與焦點控制,多了路徑與序數

連結(Link)

以直線連接二個物件也就是物件間的路徑(Path)。

訊息(Message)

訊息發生順序以自然數或杜威數等編號來表達。

活動圖(Activity Diagram)

狀態圖(State Diagram)

元件圖(Component Diagram)

部署圖(Deployment Diagram)

Apache Storm介紹

http://www.cnblogs.com/Jack47/p/storm_intro-1.html

http://ifeve.com/getting-started-with-storm-1/
http://ifeve.com/getting-started-with-storm-2/
http://ifeve.com/getting-started-with-storm-3/
http://ifeve.com/getting-started-with-storm-4/
http://ifeve.com/getting-started-with-storm-5/
http://ifeve.com/getting-started-with-storm6/
http://ifeve.com/getting-started-with-storm7/
http://ifeve.com/getting-started-of-storm8/

http://ifeve.com/author/onenote/

@Transactional 參數小技巧

1. DAO層get method最好都設定成readOnly=true, 預設值是false
2. synchronized不要加在DAO層, 應加在Service層
3. 如果synchronized method有@Transactional, 務必設定timeout

Spring Propagation types

Spring交易的屬性介紹

https://openhome.cc/Gossip/SpringGossip/TransactionAttribute.html

Propagation behavior:

MANDATORY
Support a current transaction, throw an exception if none exists.

Does not start a new Transaction, just checks whether a transaction is active (must be inside either another @Transactional method call or a programmatically created transaction)

NESTED
Execute within a nested transaction if a current transaction exists, behave likePROPAGATION_REQUIRED else.

Start a nested transaction if a transaction exists, start a new transaction otherwise.

NEVER
Execute non-transactionally, throw an exception if a transaction exists.

Does not start a transaction. Fails if a transaction is present.

NOT_SUPPORTED
Execute non-transactionally, suspend the current transaction if one exists.

Does not start a transaction. Suspends any existing transaction.

REQUIRED
Support a current transaction, create a new one if none exists.

If a transaction exists, use that, if not, create a new one. In 95% of cases, this is what you need.

REQUIRES_NEW
Create a new transaction, suspend the current transaction if one exists.

Always creates a new transaction, no matter if an existing transaction is present. If there is, it will be suspended for the duration of this method execution.

SUPPORTS
Support a current transaction, execute non-transactionally if none exists.

Can use a transaction if one is present, but doesn’t need one (and won’t start a new one either)

tomcat 遠端監控

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port={port for access}
-Dcom.sun.management.jmxremote.rmi.port={port for access}
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname={optional, bind IP}

init.d 加完以上JVM參數就可以用visualvm遠端監控了

Tomcat出現大量CLOSE_WAIT

最近遇到tomcat出現大量CLOSE_WAIT的問題, 始終找不出原因
以下是TCP連線的步驟

CLIENT                                 SERVER

1.    ESTABLISHED                    ESTABLISHED
2.    (Close)
FIN-WAIT-1  –> <FIN,ACK>  –> CLOSE-WAIT
3.    FIN-WAIT-2  <– <ACK>      <– CLOSE-WAIT
4.                                   (Close)
TIME-WAIT   <– <FIN,ACK>  <– LAST-ACK
5.    TIME-WAIT   –> <ACK>      –> CLOSED
(2 MSL)

Server端出現CLOSE_WAIT表示Server"被動地"收到關閉連線通知,Server確實關閉socket連線後會發LAST_ACK回去給Client端
通常CLOSE_WAIT出現的時間很短暫,會出現大量CLOSE_WAIT有以下幾種可能:
1. CPU資源吃緊,該請求正排隊關閉連線:此為正常現象,通常一段時間後就會消失,建議換好一點的硬體設備
2. 後端code有無窮迴圈,Server無法回應該請求:基本上這種情況可以排除,通常這類有明顯bug的code很快就會被發現,除非是天兵工程師。可用jstack或visualvm等工具查看
3. 後端code的multi-thread發生deadlock,Server無法回應該請求:檢查程式有synchronized的地方,可用jstack或visualvm等工具查看
4. 後端code有直接對Remote端發TCP packet的地方沒正確關閉連線:當Server的後端code用client類別連到Remote端,連線逾時遭到Remote端斷線,此時被動關閉連線時,code若沒處理好關閉,就會造成本地端CLOSE_WAIT
5. 某一版Tomcat或JVM的bug造成無法關閉socket

查socket語法:ss -tulpn (一些fd資訊要用sudo才會出現)
[Description] :
ss : It is a command representing utility used to investigate sockets
-t : It is an additional parameter for the ‘ss’ command used to add filter for the output for displaying TCP sockets.
-u : It is an additional parameter for the ‘ss’ command used to add filter for the output for displaying UDP sockets.
-l : It is an additional parameter for the ‘ss’ command used to add filter for the output for displaying only listening sockets.
-p : It is an additional parameter for the ‘ss’ command used to add filter for the output for displaying process associated with the sockets displayed.
-n : It is an additional parameter for the ‘ss’ command used to add filter for the output in a numeric format.

(拿到pid後)
查看socket local port:
root@hostname: /proc/7112/fd# ls -al | grep socket
查看socket local port的另一個方法:
root@hostname:/proc/7112/fd# lsof -i -a -p 7112
參考文章:http://www.dark-hamster.com/operating-system/linux/ubuntu/show-list-of-listening-services-in-linux-using-ss/

—-
問題發生原因:
http://jschu.blog.51cto.com/5594807/1732414

http://m.myexception.cn/open-source/921974.html

http://serverfault.com/questions/160558/how-to-not-get-so-many-apache-close-wait-connections

http://ahuaxuan.iteye.com/blog/657511

暴力刪除法:
https://github.com/rghose/kill-close-wait-connections

https://www.experts-exchange.com/questions/20568402/How-to-clear-CLOSE-WAIT-state-of-a-TCP-connection.html

http://www.shellhacks.com/en/HowTo-Kill-TCP-Connections-in-CLOSEWAIT-State