第十七、十八周微職位:tomcat,MogileFS
1、描述Tomcat的架構;
Tomcat組件,分為4類:
頂層類組件:包括<Server>元素和<Service>元素,它們位於整個配置文件的頂層;
連接器類組件:為<Connector>元素,代表介於客戶端與服務器端之間的通信接口,負責將客戶端的請求發送給服務器端,並將服務器的響應結果返回給客戶端;
容器類組件:代表處理客戶端請求並生成響應結果的組件,共有四類,分別為<Engine>、<Host>、<Context>和<Cluster>元素。Engine組件為特定的Service組件處理所有客戶端請求,Host組件為特定的虛擬主機處理所有的客戶端請求,Context組件為特定的Web應用處理所有的客戶端請求。Cluster組件負責為Tomcat集群系統進行會話復制、Context組件的屬性的復制,以及集群範圍內WAR文件的發布。
嵌套類組件:代表可以被嵌入到容器中的組件,如<Valve>元素和<Realm>元素等。
Tomcat元素:
<Server>元素:代表整個Servlet容器組件,是Tomcat的頂級元素。在<Server>元素中可包含一個或多個<Service>元素;
<Service>元素:包含一個<Engine>元素,以及一個或多個<Connector>元素,這些<Connector>元素共享同一個<Engine>元素;
<Connector>元素:代表和客戶端實際交互的組件,負責接收客戶端請求,以及向客戶端返回響應結果;
<Engine>元素:每個<Service>元素只能包含一個<Engine>元素。<Engine>元素處理在同一個<Service>中所有<Connector>元素接收到的客戶端請求;
<Host>元素:在一個<Engine>元素中可以包含多個<Host>元素。每個<Host>元素定義了一個虛擬主機,它可以包含一個或多個Web應用;
<Context>元素:每個<Context>元素代表了運行在虛擬主機上的單個Web應用。在一個<Host>元素中可以包含多個<Context>元素。
2、詳細解釋Tomcat的配置文件及配置文件中的參數所代表的含義;
server.xml
<Server port="8005" shutdown="SHUTDOWN"> <!--Server元素代表整個Catalina Servlet容器,是Tomcat實例的頂級元素; port,指定Tomcat服務器監聽shutdown命令的端口; shutdown,指定當終止Tomcat服務器時,發送給它的shutdown監聽端口的字符串。 --> <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> <!-- className,指定實現此Server接口的類。--> <Service name="Catalina"> <!-- Service元素用於關聯一個引擎和與此引擎相關的連接器; name,用於定義Service的名字; className,指定實現此Service接口的類--> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <!-- Connector元素是與客戶端交互的組件; port,設定監聽端口號; protocol,設定使用的協議; connectionTimeout,定義超時時長,以毫秒為單位; redirectPort,如果某連接器支持的協議是http,當接收到https請求時,轉發至此屬性定義的端口; enableLookups,是否支持服務器對客戶端進行域名解析。 --> <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol" maxThreads="150" SSLEnabled="true" > <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" /> <SSLHostConfig> <Certificate certificateKeyFile="conf/localhost-rsa-key.pem" certificateFile="conf/localhost-rsa-cert.pem" certificateChainFile="conf/localhost-rsa-chain.pem" type="RSA" /> </SSLHostConfig> </Connector> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost"> <!-- Engine是Servlet處理器的一個實例,即Servlet引擎; name,定義Engine的名字; defaultHost:指定處理客戶端請求的默認主機名; jvmRoute,定義Tomcat路由標示。 --> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <!-- 定義用於接收客戶端請求並進行相應處理的主機或虛擬主機; name,定義虛擬主機的名字; appBase,指定虛擬主機的目錄,可以指定絕對路徑,也可以指定相對於<CATALINA_HOME>的相對路徑; unpackWARs,在啟用此WebApp時是否對WAR格式的歸檔文件先進行展開; autoDeploy,在Tomcat處於運行狀態時放置於appBase目錄下的應用程序文件是否自動進行部署; alias,指定虛擬主機的別名,可以指定多個別名。 --> <Context path="/bbs" docBase="/web/threads/bbs" reloadable="true"> </Context> <!-- Context在某些意義上類似於apache中的路徑別名,一個Context定義用於標識Tomcat實例中的一個Web應用程序; path,指定訪問該Web應用的URL(相對於此Web服務器根路徑)入口,如果為"",則表示為此Webapp的根路徑; docBase,指定Web應用的存放位置; reloadable,是否允許重新加載此context相關的Web應用程序相關的類; --> <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine> </Service> </Server>
web.xml基於Java Servlet規範,可被用於每一個Java servlet容器,通常有兩個存放位置,$CATALINA_BASE/conf和每個Web應用程序(通常是WEB-INF/web.xml)。Tomcat在deploy一個應用程序時(包括重啟或重新載入),它首先讀取conf/web.xml,而後讀取WEB-INF/web.xml。 tomcat-user.xml用於實現對Tomcat資源的訪問控制,如manager-gui,admin-gui。 <role rolename="manager-gui" /> <role rolename="admin-gui" /> <user username="tomcat" password="tomcat" roles="manager-gui,admin-gui" />
3、配置Apache通過mod_proxy模塊與Tomcat連接的詳細過程;
配置:
apache主機: hostname: node4.magedu.com ip:192.168.71.130 tomcat主機: hostname: node3.magedu.com ip:192.168.71.133
前提:
apache主機: # httpd -M | grep proxy proxy_module (shared) proxy_ajp_module (shared) proxy_balancer_module (shared) proxy_http_module (shared)
apache與tomcat的http連接器進行整合:
禁用中心主機
vim /etc/httpd/conf/httpd.conf #DocumentRoot "/var/www/html"//-->註釋掉該項
創建虛擬主機
vim /etc/httpd/conf.d/proxy_mod.http.conf <VirtualHost *:80> ServerName node3.magedu.com ProxyVia On ProxyRequests Off ProxyPreserveHost On <Proxy *> Require all granted </Proxy> ProxyPass / http://192.168.71.133:8080/ ProxyPassReverse / http://192.168.71.133:8080/ <Location /> Require all granted </Location> </VirtualHost>
apache與tomcat的ajp連接器進行整合:
vim /etc/httpd/conf.d/proxy_mod.ajp.conf <VirtualHost *:80> ServerName node3.magedu.com ProxyVia On ProxyRequests Off ProxyPreserveHost On <Proxy *> Require all granted </Proxy> ProxyPass / http://192.168.71.133:8009/ ProxyPassReverse / http://192.168.71.133:8009/ <Location /> Require all granted </Location> </VirtualHost>
相關指令詳解:
ProxyPreserveHost {On|Off}:如果啟用此功能,代理會將用戶請求報文中的Host:行發送給後端的服務器,而不再使用ProxyPass指定的服務器地址。如果想在反向代理中支持虛擬主機,則需要開啟此項,否則就無需打開此功能。 ProxyVia {On|Off|Full|Block}:用於控制在http首部是否使用Via:,主要用於在多級代理中控制代理請求的流向。默認為Off,即不啟用此功能;On表示每個請求和響應報文均添加Via:;Full表示每個Via:行都會添加當前apache服務器的版本號信息;Block表示每個代理請求報文中的Via:都會被移除。 ProxyRequests {On|Off}:是否開啟apache正向代理的功能;啟用此項時為了代理http協議必須啟用mod_proxy_http模塊。同時,如果為apache設置了ProxyPass,則必須將ProxyRequests設置為Off。 ProxyPass [path] !|url [key=value key=value ...]]:將後端服務器某URL與當前服務器的某虛擬路徑關聯起來作為提供服務的路徑,path為當前服務器上的某虛擬路徑,url為後端服務器上某URL路徑。使用此指令時必須將ProxyRequests的值設置為Off。需要註意的是,如果path以“/”結尾,則對應的url也必須以“/”結尾,反之亦然。 另外,mod_proxy模塊在httpd 2.1的版本之後支持與後端服務器的連接池功能,連接在按需創建在可以保存至連接池中以備進一步使用。連接池大小或其它設定可以通過在ProxyPass中使用key=value的方式定義。常用的key如下所示: ◇ min:連接池的最小容量,此值與實際連接個數無關,僅表示連接池最小要初始化的空間大小。 ◇ max:連接池的最大容量,每個MPM都有自己獨立的容量;都值與MPM本身有關,如Prefork的總是為1,而其它的則取決於ThreadsPerChild指令的值。 ◇ loadfactor:用於負載均衡集群配置中,定義對應後端服務器的權重,取值範圍為1-100。 ◇ retry:當apache將請求發送至後端服務器得到錯誤響應時等待多長時間以後再重試。單位是秒鐘。
4、配置基於mod_jk的負載均衡;
配置
apache主機: node4.magedu.com 192.168.71.130 TomcatA主機: node3.magedu.com 192.168.71.133 TomcatB主機: node5.magedu.com 192.168.71.128
前提:編譯mod_jk時需用到apxs,所以預先安裝httpd-devel,之後編譯安裝mod_jk。
apache主機: # yum install -y httpd-devel # whereis apxs /usr/bin/apxs # tar xf tomcat-connectors-1.2.40-src.tar.gz # cd tomcat-connectors-1.2.40-src/native/ # ./configure --with-apxs=/usr/bin/apxs # make && make install TomcatA主機: # vim server.xml <Engine name="Catalina" defaultHost="localhost" jvmRoute="TomcatA"> TomcatB主機: # vim server.xml <Engine name="Catalina" defaultHost="localhost" jvmRoute="TomcatB">
配置基於mod_jk的負載均衡
# vim /etc/httpd/conf.d/http-jk.conf LoadModule jk_module modules/mod_jk.so JkWorkersFile /etc/httpd/conf.d/workers.properties JkLogFile logs/mod_jk.log JkLogLevel debug JkMount */ lbcluster1 JkMount /status/ stat1 # vim /etc/httpd/conf.d/workers.properties worker.list=lbcluster1,stat1 worker.TomcatA.type=ajp13 worker.TomcatA.host=192.168.71.133 worker.TomcatA.port=8009 worker.TomcatA.lbfactor=1 worker.TomcatB.type=ajp13 worker.TomcatB.host=192.168.71.128 worker.TomcatB.port=8009 worker.TomcatB.lbfactor=1 worker.lbcluster1.type=lb worker.lbcluster1.sticky_session=0 worker.lbcluster1.balance_workers=TomcatA,TomcatB worker.stat1.type=status
啟動服務,進行測試成功!
5、配置Tomcat集群,能夠實現用戶的session會話保持。
為node3和node5節點配置使用deltamanager:
將以下內容復制到server.xml中的Host組件中,主要修改的處為Receiver的address,若主機配置有多個ip,在默認auto情況下會報錯,最好將其修改為服務監聽的ip。 <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"> <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/> <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.1.14" port="45564" frequency="500" dropTime="3000"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="192.168.71.133" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6"/> <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> </Sender> <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/> </Channel> <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/> <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/> <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster> 6、請描述本地文件系統和分布式文件系統的特點; 文件系統是一套實現了數據的存儲、分級組織、訪問和獲取等操作的抽象數據類型(Abstract data type)(From Wikipedia)。 現在的文件系統多種多樣,不管是接口、架構、部署都有巨大差異,本文試圖總結一下本地文件系統和分布式文件系統 以及它們的特點和技術點。 本地文件系統 本地文件系統主要是指Ext2,Ext3,Btrfs,XFS這類(很難概括,只好舉例子),它們通常提供以下功能: 擴展性:隨著系統容量的增加保持性能,不隨容量變化而導致性能震蕩。比如一個目錄下的海量文件,在EXT2/3中由於目錄設計問題會導致較大的性能問題。再比如EXT2/3中的Metadata的占用和inode的劃分可能會導致空間的浪費。 數據一致性 Checksum: Checksum與對應的數據塊分開放置,避免silent corruption COW事務: COW事務參考文件系統特性 – COW事務 Log: Log被一些文件系統用作WAL模式來加快寫操作,並且保證寫操作的原子性 多設備管理:傳統上Linux往往使用LVM進行多設備的管理,現代文件系統往往增加對多設備的支持。如ZFS和Btrfs會有存儲池模型對應LVM的邏輯卷組,文件系統會對底層的多設備進行並行的訪問。 快照和克隆:采用COW事務模型的文件系統通常具有這個特性 軟件RAID支持:現代文件系統通過對多設備的管理可以很好的支持軟件RAID,如Btrfs對Metadata進行RAID1的默認保護 針對SSD的優化: 除了SSD對於隨機讀這一特性的優化外,還有對SSD擦除操作的優化。另外,SSD在使用容量接近100%時會導致極差的寫入性能,文件系統也可以對SSD的分配策略和重平衡進行一定的優化。 壓縮和加密: 現在的IO速度遠遠跟不上CPU的發展,因此對磁盤文件進行壓縮讀寫是個很好的選擇,現代文件系統往往支持多種壓縮格式,而且可以支持整個文件系統的加密或者某個文件和目錄的加密 去重: 文件系統系統去重是個大話題,主要是計算塊的checksum方法或者客戶端計算文件的hash來決定是否是一個新文件。具體參考Deduplication。 分布式文件系統 分布式文件系統的架構和實現有非常大的差異,如NFS這種傳統的基於存儲服務器的網絡文件系統,基於SAN的GPFS,然後現在的集群式架構,比如HDFS這種有中心的分布式,如GlusterFS這種無中心分布式,再如Ceph這種部分在內核態部分在用戶態等等。
NFS
GPFS
HDFS
GlusterFS
由於架構上的差異和本身文件系統的設計目標,通常分布式文件系統可以根據接口類型分成塊存儲、對象存儲和文件存儲。如Ceph具備塊存儲(Experiment)、文件存儲和對象存儲的能力,GlusterFS支持對象存儲和文件存儲的能力。而MogileFS只能作為對象存儲並且通過key來訪問。 擴展能力: 毫無疑問,擴展能力是一個分布式文件系統最重要的特點。分布式文件系統中元數據管理一般是擴展的重要問題,GFS采用元數據中心化管理,然後通過Client暫存數據分布來減小元數據的訪問壓力。GlusterFS采用無中心化管理,在客戶端采用一定的算法來對數據進行定位和獲取。 高可用性: 在分布式文件系統中,高可用性包含兩層,一是整個文件系統的可用性,二是數據的完整和一致性。整個文件系統的可用性是分布式系統的設計問題,類似於NOSQL集群的設計,比如有中心分布式系統的Master服務器,網絡分區等等。數據完整性則通過文件的鏡像和文件自動修復等手段來解決,另外,部分文件系統如GlusterFS可以依賴底層的本地文件系統提供一定支持。 協議和接口: 分布式文件系統提供給應用的接口多種多樣,Http RestFul接口、NFS接口、Ftp等等POSIX標準協議,另外通常會有自己的專用接口。 彈性存儲: 可以根據業務需要靈活地增加或縮減數據存儲以及增刪存儲池中的資源,而不需要中斷系統運行。彈性存儲的最大挑戰是減小或增加資源時的數據震蕩問題。 壓縮、加密、去重、緩存和存儲配額: 這些功能的提供往往考驗一個分布式文件系統是否具有可擴展性,一個分布式文件系統如果能方便的進行功能的添加而不影響總體的性能,那麽這個文件系統就是良好的設計。這點GlusterFS就做的非常好,它利用類似GNU/Hurd的堆棧式設計,可以讓額外的此類功能模塊非常方便的增加
名稱 適用場景 MogileFS 適用於處理海量小文件 Ceph PB級的分布式文件系統 MooseFS 適用於處理海量小文件 Taobao Filesystem 適用於處理海量小文件 GlusterFS 適於用處理單個大文件 Google Filesystem 適用於處理單個大文件 Hadoop Distributed Filesystem 適用於處理單個大文件
8、從理論原理到實戰案例來闡述MogileFS體系;
Tacker’s Database(數據庫)
數據庫保存了Mogilefs的所有元數據,你可以單獨拿數據庫服務器來做,也可以跟其他程序跑在一起,數據庫 部分非常重要,類似郵件系統的認證中心那麽重要,如果這兒掛了,那麽整個Mogilefs將處於不可用狀態。因此最好是HA結構。
Storage nodes(存儲節點)
mogstored 程序的啟動將使本機成為一個存儲節點。啟動時默認去讀/etc/mogilefs/mogstored.conf 。mogstored啟動後,便可以通過mogadm增加這臺機器到cluster中。一臺機器可以只運行一個mogstored作為存儲節點即可,也可以同時運行其他程序。
Trackers(跟蹤器)
mogilefsd即 trackers程序,類似mogilefs的wiki上介紹的,trackers做了很多工作,Replication ,Deletion,Query,Reaper,Monitor等等。mogadm,mogtool的所有操作都要跟trackers打交 道,Client的一些操作也需要定義好trackers,因此最好同時運行多個trackers來做負載均衡。trackers也可以只運行在一臺機器 上,也可以跟其他程序運行在一起,只要你配置好他的配置文件即可,默認在/etc/mogilefs/mogilefsd.conf。
工具
主要就是mogadm,mogtool這兩個工具了,用來在命令行下控制整個mogilefs系統以及查看狀態等等。
Client
Client實際上是一個Perl的pm,可以寫程序調用該pm來使用mogilefs系統,對整個系統進行讀寫操作。
原理:
每次文件的上傳和讀取,都經過前端Trackers服務器,trackers服務器收到client端的請求,查詢數據庫,返回一個上傳或者是讀取的可用的後端StorageNode的地址,然後由client端直接操作後端StorageNode服務器。upload操作返回就是成功或者失敗的結果,read操作就是返回對應的查詢數據。
環境: Tracker + Tracker database:192.168.0.21 Mogstored node1:192.168.0.22 Mogstored node2:192.168.0.23#### 安裝包
~]# ls mogilefs
MogileFS-Server-2.46-2.el6.noarch.rpm Perlbal-doc-1.78-1.el6.noarch.rpm
MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm perl-MogileFS-Client-1.14-1.el6.noarch.rpm
MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm perl-Net-Netmask-1.9015-8.el6.noarch.rpm
MogileFS-Utils-2.19-1.el6.noarch.rpm perl-Perlbal-1.78-1.el6.noarch.rpm
Perlbal-1.78-1.el6.noarch.rpm
### 在tracker和mogstored節點上安裝需要的包
~]# cd mogilefs
~]# yum install * -y
### 在tracker節點上安裝mysql
~]# yum install mysql-server -y
~]# vim /etc/my.cnf
[mysqld]
...
innodb_file_per_table=ON
sskip_name_resolve
~]# /etc/init.d/mysql start
mysql> CREATE DATABASE mogdb charset utf8;
mysql> grant all on mogdb.* to ‘moguser‘@‘192.168.0.%‘ identified by ‘mogpass‘;
mysql> flush privileges;
### 初始化mogdb庫
~]# mogdbsetup --dbname=mogdb --dbuser=moguser --dbpass=mogpass
This will attempt to setup or upgrade your MogileFS database.
It won‘t destroy existing data.
Run with --help for more information. Run with --yes to shut up these prompts.
Continue? [N/y]: y
Create/Upgrade database name ‘mogdb‘? [Y/n]: y
Grant all privileges to user ‘moguser‘, connecting from anywhere, to the mogilefs database ‘mogdb‘? [Y/n]: y
### 修改配置文件
~]# vim /etc/mogilefs/mogilefsd.conf
db_dsn = DBI:mysql:mogdb:host=192.168.0.61
db_user = moguser
db_pass = mogpass
listen = 0.0.0.0:7001
### 啟動tracker###
~]# /etc/init.d/mogilefsd start
### 在mogstored節點1創建數據掛載點
mkdir -p /data/mogstored/DEV{1,2}
chown -R mogilefs.mogilefs /data/mogstored/
### 在mogstored節點2創建數據掛載點
mkdir -p /data/mogstored/DEV{3,4}
chown -R mogilefs.mogilefs /data/mogstored/
### 修改mogstored配置文件
vim /etc/mogilefs/mogstored.conf
maxconns = 10000
httplisten = 0.0.0.0:7500
mgmtlisten = 0.0.0.0:7501
docroot = /data/mogstored #修改數據文件目錄為實際路徑
### 啟動mogstored服務
/etc/init.d/mogstored start
### 在tracker上創建host
~]# mogadm host add 192.168.0.62 --ip=192.168.0.62 --port=7500 --status=alive
~]# mogadm host add 192.168.0.63 --ip=192.168.0.63 --port=7500 --status=alive
### 創建device
~]# mogadm device add 192.168.0.62 1 #最後的數字代表設備號,如:dev1
~]# mogadm device add 192.168.0.62 2
~]# mogadm device add 192.168.0.63 3
~]# mogadm device add 192.168.0.63 4
### 查看device狀態
~]# mogadm device list
192.168.0.62 [1]: alive
used(G) free(G) total(G) weight(%)
dev1: alive 1.643 108.021 109.664 100
dev2: alive 1.643 108.021 109.664 100
192.168.0.63 [2]: alive
used(G) free(G) total(G) weight(%)
dev3: alive 1.643 108.021 109.664 100
dev4: alive 1.643 108.021 109.664 100
### 創建一個名為files的域用來存儲文件
~]# mogadm domain add files
### 將本地的/etc/fstab文件上傳至files域,並命名為fstab.txt
~]# mogupload --trackers=192.168.0.61 --domain=files --key=‘/fstab.txt‘ --file=‘/etc/fstab‘
### 查看files域中的文件
~]# moglistkeys --trackers=192.168.0.61 --domain=files
/fstab.txt
### 查看已上傳的fstab.txt文件的屬性信息
~]# mogfileinfo --trackers=192.168.0.61 --domain=files --key=‘/fstab.txt‘
- file: /fstab.txt
class: default
devcount: 2
domain: files
fid: 3
key: /fstab.txt
length: 805
- http://192.168.0.62:7500/dev1/0/000/000/0000000003.fid
- http://192.168.0.63:7500/dev3/0/000/000/0000000003.fid
### 下載fstab.txt文件到本地,並另存為fstab_dfs.txt
~]# mogfetch --trackers=192.168.0.61 --domain=files --key=‘/fstab.txt‘ --file=‘/tmp/fstab_dfs.txt
本文出自 “11822904” 博客,請務必保留此出處http://11832904.blog.51cto.com/11822904/1970441
第十七、十八周微職位:tomcat,MogileFS