<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    不急不徐,持之以恒。

    http://blog.gopersist.com/

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      24 隨筆 :: 0 文章 :: 52 評論 :: 0 Trackbacks

    #

    并發編程時,必須考慮安全性問題,即線程安全,所謂線程安全就是可以同時被多個線程調用,調用者無須額外的操作,程序也不會出現錯誤的結果。
    要使程序是線程安全的,必須考慮以下2點:
    1. 是否存在競態條件,常見的是那些先檢查后執行的操作行為,它的正確結果取決于運氣。避免錯誤結果的方法是保證操作的原子性,通常使用加鎖,也有一些原子變量類可以達到目的。
    2. 對象狀態在內存中是否可見,即當一個線程修改了對象的狀態后,其他線程不一定看到修改后的狀態。保證其他線程總是能看到最新狀態的方法有2種:一種是加鎖,另一種是使用volatile變量。
    于是得出幾個結論:
    1. 加鎖機制可保證可見性和原子性,所以能保證線程安全;
    2. 原子變量可保證原子性,但不能保證可見性,所以不能保證線程安全;
    3. volatile變量能保證可見性,但不能保證原子性,所以不能保證線程安全;
    4. volatile的原子變量能保證線程安全。
    除此之外,還有一些對象一定是線程安全的:
    1. 無狀態對象;
    2. 不可變對象。
    但是加鎖機制會產生活躍性問題,活躍性問題關注正確的行為是否一定會發生,主要有死鎖問題。
    死鎖簡單來講是這樣的:線程A持有鎖L并想獲得鎖M,同時線程B持有鎖M并想獲得鎖L,這時線程A和B都永久阻塞。
    避免死鎖的關鍵是要保證每個線程獲取鎖的順序必須相同,如上面線程A和B獲取鎖的順序如果都是先獲取鎖L再獲取鎖M,就不會發生死鎖問題。
    當持有鎖時調用外部方法,會很難分析獲取鎖的順序,要盡量避免。
    編碼參考:
    1. 將所有可變狀態都封裝在對象內部,并通過對象的內置鎖對所有訪問可變狀態的代碼進行同步;
    2. 擴展線程安全的容器類時,在新類中委托容器類的其他方法,使用新鎖,不要關心原來的容器類是否線程安全。
    參考資料:
    《JAVA并發編程實戰》
    posted @ 2014-10-10 13:41 老林 閱讀(1301) | 評論 (0)編輯 收藏

    試用Keepalived來做雙機熱備,服務器信息如下:
    服務器 操作系統 IP 虛擬IP
    Server 1 Centos 192.168.18.20 192.168.18.22
    Server 2 Centos 192.168.18.21 192.168.18.22

    1. 安裝Keepalived

    2臺Server都使用下面的命令安裝Keepalived:
    yum install keepalived -y

    2. Server1 Keepalived 配置

    $ vi /etc/keepalived/keepalived.conf

    vrrp_instance VI_1 {
        state MASTER
        interface eth0
        virtual_router_id 51
        priority 100                   # 優先級
        advert_int 1                 # 心跳間隔(秒)
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
            192.168.18.22         # 虛擬IP
        }
    }

    3. Server2 Keepalived 配置

    $ vi /etc/keepalived/keepalived.conf

    vrrp_instance VI_1 {
        state BACKUP              # 備份機
        interface eth0
        virtual_router_id 51
        priority 99                   # 優先級,比主服務器底
        advert_int 1                 # 心跳間隔(秒)
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
            192.168.18.22         # 虛擬IP
        }
    }

    4. 啟動Keepalived

    $ service keepalived start
    啟動keepalived后,可看到2臺Server都綁定了虛擬IP:
    $ ip a

    # Server 1:
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
        link/ether 00:24:8c:8c:67:43 brd ff:ff:ff:ff:ff:ff
        inet 192.168.18.20/24 brd 192.168.18.255 scope global eth0
        inet 192.168.18.22/32 scope global eth0
        inet6 fe80::224:8cff:fe8c:6743/64 scope link 
           valid_lft forever preferred_lft forever

    # Server 2:
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
        link/ether 00:23:54:bf:ab:17 brd ff:ff:ff:ff:ff:ff
        inet 192.168.18.21/24 brd 192.168.18.255 scope global eth0
        inet 192.168.18.22/32 scope global eth0
        inet6 fe80::223:54ff:febf:ab17/64 scope link 
           valid_lft forever preferred_lft forever

    5. 測試

    瀏覽器訪問http://192.168.18.22,出現 This is Server 1.
    將192.168.18.20關閉,再訪問http://192.168.18.22,出現This is Server 2.

    微信訂閱號:
    源文地址:http://blog.gopersist.com/2014/09/24/keepalived/
    posted @ 2014-09-24 11:34 老林 閱讀(2052) | 評論 (2)編輯 收藏

    試用IPVS的直接路由方式來做負載均衡。服務器信息如下:


     

    IP配置信息如下:

    服務器

    操作系統

    IP

    IP別名

    網關

    調度服務器

    Centos

    192.168.2.90

    192.168.2.99

    192.168.2.1

    實際服務器

    Centos

    192.168.2.71

    192.168.2.99

    192.168.2.1

    Centos

    192.168.2.72

    192.168.2.99

    192.168.2.1

     

    直接路由方式工作在數據鏈路層,通過修改數據包的MAC地址,將數據包轉發到實際服務器上。實際服務器響應時直接發送給用戶端,而不經過調度器。

     

    因為調度服務器并沒有修改數據包的IP地址,所以我們需要為實際服務器設置與調度服務器相同的IP別名,以使實際服務器接受數據包。

     

    為調度服務器設置IP別名:

    ifconfig eth1:0 192.168.2.99

    IP別名與原來的IP地址在使用上并沒有什么不同,這里可以ping9099兩個IP

     

    為實際服務器設置IP別名:

    ifconfig lo:0 192.168.2.99 broadcast 192.168.2.99 netmask 255.255.255.255 up

    為實際服務器添加路由規則,使它不去尋找其他擁有這個IP的服務器:

    route add -host 192.168.2.99 dev lo:0

    防止實際服務器響應針對IP別名的ARP廣播:

    echo 1>/proc/sys/net/ipv4/conf/lo/arp_ignore

    echo 2>/proc/sys/net/ipv4/conf/lo/arp_announce

    echo 1>/proc/sys/net/ipv4/conf/all/arp_ignore

    echo 2>/proc/sys/net/ipv4/conf/all/arp_announce

     

    使用ipvsadm配置調度服務器:

    ipvsadm -A -t 192.168.2.99:8888 -s rr

    ipvsadm -a -t 192.168.2.99:8888 -r 192.168.2.71:8888 -g

    ipvsadm -a -t 192.168.2.99:8888 -r 192.168.2.72:8888 -g

     

    使用下面的命令將連接有效時間改為1秒來測試,:

    ipvsadm --set 1 120 300

     

    瀏覽器訪問http://192.168.2.99:8888,每隔1秒多點擊刷新,就會交替出現192.168.2.71192.168.2.72

     

    posted @ 2014-04-28 11:15 老林 閱讀(889) | 評論 (0)編輯 收藏

    試用IPVS來做負載均衡,使用了1臺雙網卡服務器和2臺單網卡服務器,2個網段。服務器信息如下:



    IP配置信息如下:

    服務器

    操作系統

    網卡

    IP

    調度服務器

    Centos

    eth0

    192.168.18.58

    eth1

    192.168.2.90

    實際服務器

    Centos

    eth0

    192.168.2.71

    Centos

    eth0

    192.168.2.72

     

    1.         首先配置調度服務器:

     

    a)         IPVS模塊已經內置到linux2.6.x內核中,可以通過下面的命令查看是否已安裝:

    modprobe -l | grep ipvs

    看到類似下面的輸出,表示已經安裝了

    kernel/net/netfilter/ipvs/ip_vs.ko

    kernel/net/netfilter/ipvs/ip_vs_rr.ko

    kernel/net/netfilter/ipvs/ip_vs_wrr.ko

    kernel/net/netfilter/ipvs/ip_vs_lc.ko

    kernel/net/netfilter/ipvs/ip_vs_wlc.ko

    kernel/net/netfilter/ipvs/ip_vs_lblc.ko

    kernel/net/netfilter/ipvs/ip_vs_lblcr.ko

    kernel/net/netfilter/ipvs/ip_vs_dh.ko

    kernel/net/netfilter/ipvs/ip_vs_sh.ko

    kernel/net/netfilter/ipvs/ip_vs_sed.ko

    kernel/net/netfilter/ipvs/ip_vs_nq.ko

    kernel/net/netfilter/ipvs/ip_vs_ftp.ko

    kernel/net/netfilter/ipvs/ip_vs_pe_sip.ko

     

    b)         安裝IPVS的管理工具ipvsadm

    yum install -y ipvsadm

     

    c)         清除表中所有記錄:

    ipvsadm -C

    使用下面的命令增加虛擬服務器,采用輪詢調度策略:

    ipvsadm -A -t 192.168.18.58:8888 -s rr

     

    使用下面的命令添加實際服務器,并采用NAT方式轉發數據包:

    ipvsadm -a -t 192.168.18.58:8888 -r 192.168.2.71:9999 -m

    ipvsadm -a -t 192.168.18.58:8888 -r 192.168.2.72:9999 -m

     

    d)         打開數據包轉發:

    echo 1 > /proc/sys/net/ipv4/ip_forward

     

    2.         接下來配置2臺實際服務器,分別做以下工作:

     

    a)         9999端口上啟動一個web服務:

    配置好web服務后,當訪問http://192.168.2.71:9999時,頁面返回:This is 192.168.2.71.;當訪問http://192.168.2.72:9999時,頁面返回:This is 192.168.2.72.

     

    b)         設置默認網關指向調度服務器

    route del default

    route add default gw 192.168.2.90

     

    3.         測試

     

    訪問192.168.18.58:8888,會顯示This is 192.168.2.71This is 192.168.2.72,多次刷新應該要交替出現7172,但實際上并沒有這樣,瀏覽器只顯示與第一次相同的內容,也就是ipvsadm每次都選擇了同一臺服務器。這是因為當一個TCP連接的初始SYN報文到達時,IPVS就選擇了一臺服務器,后繼報文會被轉發到相同的服務器。這個TCP連接在ipvsadm中默認有效時間為15分鐘,可以通過下面的命令查看:

    ipvsadm -L --timeout

    Timeout (tcp tcpfin udp): 900 120 300

    現在將有效時間改為1秒來測試,使用下面的命令:

    ipvsadm --set 1 120 300

     

    再到瀏覽器中每隔1秒多點擊刷新,就會交替出現7172,說明輪詢調度正在正常工作。

     

     

    posted @ 2014-04-25 14:32 老林 閱讀(1375) | 評論 (0)編輯 收藏

    為了搞清楚iptables NAT的過程,做了這個實驗。使用了1臺雙網卡服務器和1臺單網卡服務器,2個網段。服務器信息如下:


    IP配置信息如下:

    服務器

    操作系統

    網卡

    IP

    調度服務器

    Centos

    eth0

    192.168.18.58

    eth1

    192.168.2.90

    實際服務器

    Centos

    eth0

    192.168.2.73

     

    1.       為了看到調度服務器上的數據轉發過程,首先在調度服務器上分出內核的debug日志:

    /etc/rsyslog.conf最后增加:kern.debug /var/log/iptables.log

    重啟日志服務:/etc/init.d/rsyslog restart

     

    2.       啟動調度服務器的iptables并清空規則

    service iptables start

    iptables -F

     

    3.       增加調度服務器的iptables特定日志輸出

    假設要將對調度服務器8888端口的訪問轉發給實際服務器的9999端口處理,在iptables中增加與這2個端口相關的日志輸出:

    iptables -t mangle -A PREROUTING -p tcp --dport 8888 -j LOG --log-level debug --log-prefix "<<<<< PER IN:"

    iptables -t mangle -A PREROUTING -p tcp --sport 9999 -j LOG --log-level debug --log-prefix "<<<<< PER IN:"

    iptables -t mangle -A POSTROUTING -p tcp --sport 8888 -j LOG --log-level debug --log-prefix ">>>>> POST OUT:"

    iptables -t mangle -A POSTROUTING -p tcp --dport 9999 -j LOG --log-level debug --log-prefix ">>>>> POST OUT:"

    iptables -t mangle -A POSTROUTING -p tcp --sport 9999 -j LOG --log-level debug --log-prefix ">>>>> POST OUT:"

     

    這時,通過瀏覽器訪問http://192.168.18.58:8888可以看到iptables.log中打印出下面的日志:

    Apr 24 16:24:35 route-server1 kernel: <<<<< PER IN:IN=eth0 OUT= MAC=00:1f:c6:cb:eb:e0:00:1f:33:de:29:ad:08:00 SRC=192.168.18.25 DST=192.168.18.58 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=28721 DF PROTO=TCP SPT=50270 DPT=8888 WINDOW=14600 RES=0x00 SYN URGP=0

    Apr 24 16:24:35 route-server1 kernel: <<<<< POST OUT:IN= OUT=eth0 SRC=192.168.18.58 DST=192.168.18.25 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=8888 DPT=50270 WINDOW=0 RES=0x00 ACK RST URGP=0

     

    雖然這個端口上即沒有應用,也沒有將請求轉發出去,但日志打印出了內核獲取到的對這個端口的請求。

     

    4.       配置iptables將對8888的請求轉發到192.168.2.73:9999

    iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8888 -j DNAT --to-destination 192.168.2.73:9999

     

    訪問http://192.168.18.58:8888,日志中打印如下信息:

    Apr 24 16:39:21 route-server1 kernel: <<<<< PER IN:IN=eth0 OUT= MAC=00:1f:c6:cb:eb:e0:00:1f:33:de:29:ad:08:00 SRC=192.168.18.25 DST=192.168.18.58 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=56888 DF PROTO=TCP SPT=50274 DPT=8888 WINDOW=14600 RES=0x00 SYN URGP=0

     

    日志中只打印了從eth0收到的對8888端口的請求,這是因為當數據要被轉發到192.168.2.73:9999時,默認情況下被禁止了。

     

    5.       打開數據包轉發功能

    echo 1 > /proc/sys/net/ipv4/ip_forward

     

    訪問http://192.168.18.58:8888,日志中打印如下信息:

    Apr 24 16:39:21 route-server1 kernel: <<<<< PER IN:IN=eth0 OUT= MAC=00:1f:c6:cb:eb:e0:00:1f:33:de:29:ad:08:00 SRC=192.168.18.25 DST=192.168.18.58 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=56888 DF PROTO=TCP SPT=50274 DPT=8888 WINDOW=14600 RES=0x00 SYN URGP=0

    Apr 24 16:39:21 route-server1 kernel: <<<<< POST OUT:IN= OUT=eth1 SRC=192.168.18.25 DST=192.168.2.73 LEN=60 TOS=0x00 PREC=0x00 TTL=62 ID=56888 DF PROTO=TCP SPT=50274 DPT=9999 WINDOW=14600 RES=0x00 SYN URGP=0

     

    第一條日志顯示從eth0收到了對8888端口的請求,第二條日志顯示iptables已經更改了數據包的目的地為192.168.2.73:9999,并通過eth1發出去。

     

    但這時請求雖然已經被轉發到實際處理的服務器,但調度服務器收不到響應,瀏覽器仍在不停重試,日志也在不斷打印。這是因為實際服務器收到的數據包的來源IP是另一個網段的,實際服務器回復時,發現不是本網段的就把數據包發給網關,網關設置的是192.168.2.1,這時數據就丟了。

     

    6.       將實際服務器的默認網關設置為192.168.2.90

    在實際服務器上執行以下命令:

    route del default

    route add default gw 192.168.2.90

     

    再次訪問http://192.168.18.58:8888,日志打印如下信息:

    Apr 24 16:47:27 route-server1 kernel: <<<<< PER IN:IN=eth0 OUT= MAC=00:1f:c6:cb:eb:e0:00:1f:33:de:29:ad:08:00 SRC=192.168.18.25 DST=192.168.18.58 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=37000 DF PROTO=TCP SPT=50279 DPT=8888 WINDOW=14600 RES=0x00 SYN URGP=0

    Apr 24 16:47:27 route-server1 kernel: <<<<< POST OUT:IN= OUT=eth1 SRC=192.168.18.25 DST=192.168.2.73 LEN=60 TOS=0x00 PREC=0x00 TTL=62 ID=37000 DF PROTO=TCP SPT=50279 DPT=9999 WINDOW=14600 RES=0x00 SYN URGP=0

    Apr 24 16:47:27 route-server1 kernel: <<<<< PER IN:IN=eth1 OUT= MAC=00:22:b0:de:f7:49:00:24:8c:b4:a1:8c:08:00 SRC=192.168.2.73 DST=192.168.18.25 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=9999 DPT=50279 WINDOW=0 RES=0x00 ACK RST URGP=0

    Apr 24 16:47:27 route-server1 kernel: <<<<< POST OUT:IN= OUT=eth0 SRC=192.168.2.73 DST=192.168.18.25 LEN=40 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=9999 DPT=50279 WINDOW=0 RES=0x00 ACK RST URGP=0

     

    上面第一條第二條日志和之前一樣,iptables將目地址更改后,通過eth1網卡發送出去。第三條日志通過eth1網卡接收到了實際服務器發送過來的數據,并在第四條日志中通過eth0發回請求方。

     

    posted @ 2014-04-24 17:15 老林 閱讀(3983) | 評論 (0)編輯 收藏

    一、準備
    1. 安裝apache,http://httpd.apache.org/
    2. 安裝perl, http://www.perl.org/
    3. 安裝awstat, http://awstats.sourceforge.net/
    awstat安裝會自動進行一些配置,可能不需要下面的設置。
    二、apache配置
    在apache安裝目錄conf\httpd.conf中增加以下配置:
    Alias /awstatsclasses "C:/Program Files/AWStats/wwwroot/classes/"
    Alias /awstatscss "C:/Program Files/AWStats/wwwroot/wwwroot/css/"
    Alias /awstatsicons "C:/Program Files/AWStats/wwwroot/icon/"
    ScriptAlias /awstats/ "C:/Program Files/AWStats/wwwroot/cgi-bin/"

    <Directory "C:/Program Files/AWStats/wwwroot/cgi-bin/">
        AllowOverride None
        Options ExecCGI
        Order allow,deny
        Allow from all
    </Directory>

    將common注釋掉,放開combined的注釋
    #CustomLog "logs/access.log" common
    CustomLog "logs/access.log" combined
    三、awstat配置
    1. 修改{awstats_home}/wwwroot/cgi-bin/下的awredir.plawstats.pl文件的第一行從#!/usr/bin/perl改成#!C:\strawberry\perl\bin\perl.exe。
    3. 
    修改{awstats_home}/wwwroot/cgi-bin/下的awstats.demo.conf
    LogFile="C:\Program Files\Apache Software Foundation\Apache2.2\logs\access.log"
    LogType=W
    LogFormat=1
    SiteDomain="demo"
    四、更新報表
    命令行進行{awstats_home}\wwwroot\cgi-bin
    perl awstats.pl -config=demo –update
    五、訪問統計報表
    http://localhost/awstats/awstats.pl?config=demo
    注意:httpd.conf更改后要重啟apache服務
    posted @ 2010-11-11 23:36 老林 閱讀(628) | 評論 (0)編輯 收藏

         摘要: Play Framework Eclipse 開發入門  閱讀全文
    posted @ 2010-10-30 13:18 老林 閱讀(5774) | 評論 (4)編輯 收藏

         摘要: 一個軟件實體,應當對擴展開放,對修改關閉。
    要求一個軟件系統可以在不修改原有代碼的情況下,通過擴展達到增強其功能的目的。  閱讀全文
    posted @ 2010-03-30 08:44 老林 閱讀(2041) | 評論 (1)編輯 收藏

         摘要: Struts2與JasperReport無縫整合,使用iReport設計報表,取JavaBean數據源、類導航取值、排序、分組、參數傳遞、分頁...  閱讀全文
    posted @ 2010-03-12 23:54 老林 閱讀(6351) | 評論 (8)編輯 收藏

         摘要: 之前整合的框架中struts部分有問題,現將其升級到strtus2.1.8.1,可以解決兩個問題:
    1. 程序工作正常但后臺報錯,Unable to set parameter [location] in result of type [com.googlecode.jsonplugin.JSONResult]。
    2. 無法提交double為0值的問題。 ...  閱讀全文
    posted @ 2010-01-29 23:34 老林 閱讀(1033) | 評論 (0)編輯 收藏

    僅列出標題
    共3頁: 上一頁 1 2 3 下一頁 
    主站蜘蛛池模板: 美女露100%胸无遮挡免费观看| 亚洲网站在线观看| 久久精品免费视频观看| 免费人成视网站在线观看不卡| 国产成人亚洲精品蜜芽影院| 成人A毛片免费观看网站| 国产精品xxxx国产喷水亚洲国产精品无码久久一区| 亚洲欧美日韩中文二区| 国产麻豆免费观看91| 无码人妻精品一二三区免费| 亚洲一区二区三区无码国产| 91在线品视觉盛宴免费| 久久久久久a亚洲欧洲aⅴ| 黄色片免费在线观看| 亚洲精品在线电影| 午夜色a大片在线观看免费| 亚洲av无码一区二区三区四区| 免费国产高清视频| 美女巨胸喷奶水视频www免费| 亚洲精品字幕在线观看| 99久久免费国产香蕉麻豆| 在线亚洲高清揄拍自拍一品区 | 无码日韩精品一区二区免费暖暖| 亚洲AV无一区二区三区久久| 国产精品视频免费| 免费人妻精品一区二区三区| 久久久久无码精品亚洲日韩| 日本成年免费网站| 永久免费无码网站在线观看个| 免费观看一级毛片| 国产精品午夜免费观看网站| 国产免费牲交视频| 国产免费无码AV片在线观看不卡 | 韩国欧洲一级毛片免费| 国产精品免费久久久久久久久| 亚洲网站在线观看| 亚洲av成人一区二区三区在线观看 | 亚洲av午夜福利精品一区人妖| 69成人免费视频| 中文字幕一区二区三区免费视频| 亚洲欧洲日韩在线电影|