一、描述Tomcat的架構;html
Tomcat組件,分爲4類:前端
頂層類組件:包括<Server>元素和<Service>元素,它們位於整個配置文件的頂層;node
鏈接器類組件:爲<Connector>元素,表明介於客戶端與服務器端之間的通訊接口,負責將客戶端的請求發送給服務器端,並將服務器的響應結果返回給客戶端;python
容器類組件:表明處理客戶端請求並生成響應結果的組件,共有四類,分別爲<Engine>、<Host>、<Context>和<Cluster>元素。Engine組件爲特定的Service組件處理全部客戶端請求,Host組件爲特定的虛擬主機處理全部的客戶端請求,Context組件爲特定的Web應用處理全部的客戶端請求。Cluster組件負責爲Tomcat集羣系統進行會話複製、Context組件的屬性的複製,以及集羣範圍內WAR文件的發佈。mysql
嵌套類組件:表明能夠被嵌入到容器中的組件,如<Valve>元素和<Realm>元素等。web
Tomcat元素:算法
<Server>元素:表明整個Servlet容器組件,是Tomcat的頂級元素。在<Server>元素中可包含一個或多個<Service>元素;sql
<Service>元素:包含一個<Engine>元素,以及一個或多個<Connector>元素,這些<Connector>元素共享同一個<Engine>元素;數據庫
<Connector>元素:表明和客戶端實際交互的組件,負責接收客戶端請求,以及向客戶端返回響應結果;apache
<Engine>元素:每一個<Service>元素只能包含一個<Engine>元素。<Engine>元素處理在同一個<Service>中全部<Connector>元素接收到的客戶端請求;
<Host>元素:在一個<Engine>元素中能夠包含多個<Host>元素。每一個<Host>元素定義了一個虛擬主機,它能夠包含一個或多個Web應用;
<Context>元素:每一個<Context>元素表明了運行在虛擬主機上的單個Web應用。在一個<Host>元素中能夠包含多個<Context>元素。
二、詳細解釋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" />
三、配置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)
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/ ProxyPa***everse / http://192.168.71.133:8080/ <Location /> Require all granted </Location> </VirtualHost>
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/ ProxyPa***everse / 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將請求發送至後端服務器獲得錯誤響應時等待多長時間之後再重試。單位是秒鐘。
apache主機: node4.magedu.com 192.168.71.130 TomcatA主機: node3.magedu.com 192.168.71.133 TomcatB主機: node5.magedu.com 192.168.71.128
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">
# 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
啓動服務,進行測試成功!
將如下內容複製到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> 六、請描述本地文件系統和分佈式文件系統的特色; 文件系統是一套實現了數據的存儲、分級組織、訪問和獲取等操做的抽象數據類型(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 適用於處理單個大文件
八、從理論原理到實戰案例來闡述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