一、描述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