Linux 权限详解

前言

上面的命令的意思是将文档 test.txt 的权限改为 rwxrwx—,而 770 代表是什么含义呢。本篇文章就来详细介绍 Linux 下档案的权限。

用户角色

在介绍档案权限之前先来介绍 Linux 中有哪几种用户角色。

  • owner — 档案拥有者;
  • group — 群组;
  • other — 其他人,除了档案拥有者和同一群组的其他人。

文档属性

登陆之后使用 ls -al,得到结果如下图 7 组属性。

这里写图片描述

第一列:代表文档的类型和权限(本篇文章主要内容);
第二列:代表有多少档案连结到此节点(不做具体阐述);
第三列:代表文档拥有者;
第四列:代表文档所属群组;
第五列:代表文档大小;
第六列:代表文档日期或者最近修改日期
第七列:代表文档名称

第一列中的十个属性,可以分为四组,如下图:

这里写图片描述

第一组,代表这个档案的类型:

  • d: 代表目录;
  • -: 代表文档;
  • l: 代表连结;
  • b: 装置文件里面的可供储存的接口讴备(可随机存取装置);
  • c: 装置文件里面的串行端口讴备,例如键盘、鼠标(一次怅读取装置)。

第二,三,四组,分别表示档案拥有者,通群组和其他人对此文档的权限:

  • r — 读权限
  • w — 写权限
  • x — 可执行权限

所以,上图中 .Trash 的文件类型是路径;它的拥有者对它有读写和执行的权限;它的所属群组里的用户对它没有读写和执行的权限;其他人对它没有读写和执行的权限。

权限对目录和文档的意义

权限对目录的意义

  • r — 表示对此目录具有读取目录结构列表的权限,可以查询该目录下的文件名,可以使用 ls 命令列出该目录的内容列表。
  • w — 具有异劢该目彔结构列表的权限,也就是底下这些权限:
    1. 建立新的档案和目录
    2. 删除已存在的档案和目录
    3. 重命名已存在的档案和目录
    4. 移动目录内的档案和目录
  • x — 表示能否进入该目录,如果没有此权限将不能进入此目录。

权限对文档的意义

  • r — 可以读取该文档的内容;
  • w — 可以修改该文档的内容,但不能删除该文档;
  • x — 该档案具有可以被系统执行的权限。

改变档案属性和权限

改变所属群组(chgrp)

使用命令 chgrp 可以改变档案拥有者。命令具体用法如下:

groupname:将要改为的群组名称;
dirname/filename: 档案路径和名称。

改变档案拥有者(chown)

使用命令 chown 可以改变档案拥有者。命令具体用法如下:

username: 将要改为的拥有者的用户名;
dirname/filename: 档案路径和名称。

修改档案权限

使用命令 chmod 修改档案权限。修改档案的权限有多种方式。命令格式如下:

mod:想要变更为的权限;
dirname/filename: 档案路径和名称。

数字类型方式

档案的基本权限有九个,分别是 owner/group/other 的 read/write/execute 权限。可以用数字代表各个权限。各个权限对应的数字如下:

  • r (read) — 4;
  • w (write) — 2;
  • x (execute) — 1。

每种角色(owner/group/other)都有自己的三个权限数,把这三个权限数累加就代表此角色的权限。例如;-rwxr-xr–,把它转成数字表示为:

owner = 4 + 2 + 1 = 7;
group = 4 + 0 + 1= 5;
other = 4 + 0 + 0 = 4;

所以,如果我们想让上图中 .Trash 的同群组的用户对其有读的权限,即 drwxr—– ,我们就可以使用如下命令:

符号类型方式

我们使用 u/g/o 分别代表,文档拥有者/群组/其他人,a 代表所有角色。使用 r/w/x 分别代表,读/写/执行。使用 +/-/= 分别代表,加入/减去/设定。同样的如果我们想让上图中 .Trash 的同群组的用户对其有读的权限,即 drwxr—– ,我们就可以使用如下命令:

但是,如果我们不知文档原有的权限是什么,只想给同群组的添加读权限,其他不变,我们就不方便使用 = 了。可以使用 + ,如下:

如果只想去掉拥有者的写权限,可以使用 – ,如下:

注意: chgrp,chown,chmod 都需要 root 身份才能执行

runC入门

runC入门

这周在旧金山举行的DockerCon大会上, 开放容器项目 和一个运行容器的CLI工具runC同时和大家见面。runC是一个包装的 libcontainer

它是Docker捐献给开放容器项目用来作为参考实现的。这听起来很有意思,尤其是主要的供应商是OCP的一部分,就像rkt之于CoreOS。

让我们签出 runC 源码用它把Docker容器跑起来吧。

安装runC

runC目前不提供二进制源。需要先安装Go语言环境,然后签出runC代码才能编译runC:

bash
mkdir -p ~/golang/src/github.com/opencontainers/
cd ~/golang/src/github.com/opencontainers/
git clone https://github.com/opencontainers/runc
cd ./runc
make
sudo make install

以上这些指令是在Ubuntu14.04机器上运行的,并未在其他环境验证。

现在,你应该编译得到自己的二进制runC了。

运行一个容器

runC的运行级别比Docker更低,因此他只需要镜像文件在文件夹或者包文件中。

我们使用正在运行的Docker容器导出一个打包文件并解压到文件夹中即可。

bash
mkdir ./goapp
cd ./goapp
docker pull geku/go-app:0.1
CONTAINER_ID=$(docker run -d geku/go-app:0.1)
docker export -o go-app.tar $CONTAINER_ID
tar -xf go-app.tar
rm go-app.tar

现在我们的文件中都是容器文件。我们必须先创建 container.json 文件,然后运行它。

bash
{
"version": "0.1",
"os": "linux",
"arch": "amd64",
"processes": [
{
"tty": true,
"user": "daemon",
"args": [
"/app/go-app"
],
"env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TERM=xterm"
],
"cwd": ""
}
],
"root": {
"path": "./",
"readonly": true
},
"cpus": 1.1,
"memory": 128,
"namespaces": [
{
"type": "process"
},
{
"type": "mount"
},
{
"type": "ipc"
}
],
"capabilities": [
"AUDIT_WRITE",
"KILL",
"NET_BIND_SERVICE"
],
"devices": [
"null",
"random",
"full",
"tty",
"zero",
"urandom"
],
"mounts": [
{
"type": "proc",
"source": "proc",
"destination": "/proc",
"options": ""
},
{
"type": "tmpfs",
"source": "tmpfs",
"destination": "/dev",
"options": "nosuid,strictatime,mode=755,size=65536k"
},
{
"type": "devpts",
"source": "devpts",
"destination": "/dev/pts",
"options": "nosuid,noexec,newinstance,ptmxmode=0666,mode=0620,gid=5"
},
{
"type": "tmpfs",
"source": "shm",
"destination": "/dev/shm",
"options": "nosuid,noexec,nodev,mode=1777,size=65536k"
},
{
"type": "mqueue",
"source": "mqueue",
"destination": "/dev/mqueue",
"options": "nosuid,noexec,nodev"
},
{
"type": "sysfs",
"source": "sysfs",
"destination": "/sys",
"options": "nosuid,noexec,nodev"
}
]
}

当运行 runc spec 时,runC工具根据上面的一些配置生成容器。很显然,我们必须在 processes/args

设置过程命令而且要移除 network ,再将 uts 命名空间分享到主机网络。基于以上原因,

我们也应该移除不必要的 hostname 。最后我们还应该设置一下 root path为 ./.

当准备启动一个容器时确保我们的 container.json 存在镜像的root根目录。

bash
cd ./goapp
sudo runc

为了验证容器内部的应用程序是否正在运行,我们可以发送一个HTTP请求:

bash
curl localhost:5000/json
{"hostname":"demo","env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TERM=xterm","HOME=/usr/sbin"],"num_cpu":4,"go_max_procs":1}

哇,我们的第一个容器使用runC开始运行了!这是一个简单的例子,但演示了如何使用runC运行Docker镜像。

traefik简介

traefik(https://traefik.io/)是一款开源的反向代理与负载均衡工具。它最大的优点是能够与常见的微服务系统直接整合,可以实现自动化动态配置。目前支持Docker, Swarm, Mesos/Marathon, Mesos, Kubernetes, Consul, Etcd, Zookeeper, BoltDB, Rest API等等后端模型。

traefik的具体模型如下:

为什么选择traefik?

事实上在之前我对LB的选择一直更倾向于使用 HAProxy 。但是选择traefik主要是有以下特点让我们决定使用:

  • Golang编写,单文件部署,与系统无关,同时也提供小尺寸Docker镜像。
  • 支持Docker/Etcd后端,天然连接我们的微服务集群。
  • 内置Web UI,管理相对方便。
  • 自动配置ACME(Let’s Encrypt)证书功能。
  • 性能尚可,我们也没有到压榨LB性能的阶段,易用性更重要。

除了这些以外,traefik还有以下特点:

  • Restful API支持。
  • 支持后端健康状态检查,根据状态自动配置。
  • 支持动态加载配置文件和graceful重启。
  • 支持WebSocket和HTTP/2。

除了上面提到的微服务化集群支持,一些AB测试阶段也可以通过frontend的路由特性进行动态分配,当然这些对HAProxy等软件都是标准支持的。

traefik的配置

traefik支持的配置方式支持文件方式进行配置,这个也是比较常见的配置方式,我们这里简单介绍一下。

traefik支持的toml方式进行配置,官方提供了一个 示例的traefik.toml文件 用于演示配置。除此之外,后端服务一般是采用单独文件进行存储,比如演示配置中指定的rules.toml。

具体一个例子,如果我们有两个后端,127.0.0.1:7727,127.0.0.1:7728,我们希望所有的Chrome用户都可以访问127.0.0.1:7727,其它人都访问127.0.0.1:7728,这样这个rules.toml应该如何配置呢?

# rules.toml
[backends]
  [backends.backend1]
    [backends.backend1.servers.server1]
    url = "http://127.0.0.1:7727"
  [backends.backend2]
    [backends.backend2.servers.server1]
    url = "http://127.0.0.1:7728"


[frontends]
  [frontends.frontend1]
  entrypoints = ["http"]
  backend = "backend1"
    [frontends.frontend1.routes.test_1]
    rule = "HeadersRegexp: User-Agent, Chrome"
  [frontends.frontend2]
  entrypoints = ["http"]
  backend = "backend2"

首先定义两个后端服务,每个后端服务可以支持多个服务单元,这里我们只有一个。前端frontends用于匹配请求落到哪个后端服务中。我们这里定义一个规则test_1,设置规则为根据HTTP请求头部正则进行分配:如果UserAgent中包含Chrome字样,则访问到127.0.0.1:7727。匹配的规则方式包含了以下几种方式:

  • Headers / HeaderRegexp : 头部匹配方式,分别对应按值和正则表达式两种方式。
  • Host / HostRegexp : 按照请求主机名进行匹配,与头部信息相似。
  • Method : 按照请求方式区分。
  • Path / PathStrip / PathPrefix / PathPrefixStrip : 按照路径区分后端。

traefik与微服务集群

这个有人已经写过相关的文章了,这里简单推荐一下: Microservices Bliss with Docker and Traefik中文译文

Docker管理工具Shipyard安装配置

shipyard是一个基于Web的Docker管理工具,基于Docker Swarm,支持多主机,可以把多个Docker主机上的容器统一管理;可以查看镜像,下拉镜像;可以管理私有镜像仓库;并提供 RESTful API 等。本文将在两台docker主机上安装配置shipyard并分别在不同的Docker上发布两个MySQL实例,MySQL-dev与MySQL-Online。
环境准备 centos 7 + docker 1.9.1,准备两台。
主节点:docker41,IP:192.168.199.41;
从节点:docker42,IP:192.168.199.42。
1.Shipyard生态介绍
shipyard是由shipyard控制器以及周围生态系统构成,都是以容器封装,以下按照启动顺序进行介绍。
1)RethinkDB
首先启动的就是RethinkDB容器,shipyard采用RethinkDB作为数据库来保存账户,引擎,服务键值以及元信息等信息。
2)Discovery
为了使用Swarm的选举机制,我们需要一个外部的密钥值存储容器,shipyard默认采用了etcd
3)shipyard_certs
证书管理容器,实现证书验证功能
4)Proxy
默认情况下,Docker引擎只监听Socket,我们可以重新配置引擎使用TLS或者使用一个代理容器,转发请求从TCP到Docker监听的UNIX Socket。
5)Swarm Manager
Swarm管理器
6)Swarm Agent
Swarm代理,运行在每个节点上。
7)Controller
shipyard控制器,Remote API的实现和web的实现。
2.准备工作
在两台主机上分别做几下两点。
1)首先清除iptables
#iptables -F
2016-01-22_19-22-52
2)设置daemon参数,重启docker
#vi /usr/lib/systemd/system/docker.service


ExecStart=/usr/bin/docker daemon -H unix:///var/run/docker.sock

2016-01-22_19-22-23
3.Shipyard主节点安装(IP:192.168.199.41)
1)下拉镜像
虽然官网提供了一键安装的命令,curl -sSL https://shipyard-project.com/deploy | bash -s , 但我们还是体验一下non-TLS手工安装,也就是说不安装shipyard_certs。所以我们先下拉以下几个镜像。
docker pull rethinkdb
docker pull microbox/etcd
docker pull shipyard/docker-proxy
docker pull swarm:latest
docker pull shipyard/shipyard
2016-01-22_19-18-51
如果在下拉镜像速度上有问题,建议使用国内的镜像代理。
2)启动容器shipyard-rethinkdb


docker run \
    -ti \
    -d \
    --restart=always \
    --name shipyard-rethinkdb \
    rethinkdb

3)启动容器shipyard-discovery


docker run \
    -ti \
    -d \
    -p 4001:4001 \
    -p 7001:7001 \
    --restart=always \
    --name shipyard-discovery \
    microbox/etcd -name discovery

2016-01-22_19-25-11
4)启动shipyard-proxy


docker run \
    -ti \
    -d \
    -p 2375:2375 \
    --hostname=$HOSTNAME \
    --restart=always \
    --name shipyard-proxy \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -e PORT=2375 \
    shipyard/docker-proxy:latest

2016-01-22_19-25-34
5)启动shipyard-swarm-manager


docker run \
    -ti \
    -d \
    --restart=always \
    --name shipyard-swarm-manager \
    swarm:latest \
    manage --replication --addr 192.168.199.41:3375 --host tcp://0.0.0.0:3375 etcd://192.168.199.41:4001

2016-01-22_22-46-33
6)启动shipyard-swarm-agent


docker run \
    -ti \
    -d \
    --restart=always \
    --name shipyard-swarm-agent \
    swarm:latest \
    join --addr 192.168.199.41:2375 etcd://192.168.199.41:4001

2016-01-22_19-26-28
7)启动shipyard-controller


docker run \
    -ti \
    -d \
    --restart=always \
    --name shipyard-controller \
    --link shipyard-rethinkdb:rethinkdb \
    --link shipyard-swarm-manager:swarm \
    -p 8080:8080 \
    shipyard/shipyard:latest \
    server \
    -d tcp://swarm:3375

2016-01-22_19-26-40
至此主节点安装完毕,我们可以查看log来检查是否安装成功。
8)Web界面访问
访问http://192.168.199.41:8080,输入默认用户名和密码:admin/shipyard
查看启动的容器
2016-01-22_19-27-55
查看镜像
2016-01-22_19-28-11
查看节点,此时只有docker41这个节点
2016-01-22_19-29-11
4.添加从节点(IP:192.168.199.42)
1)下拉镜像
docker pull shipyard/docker-proxy
docker pull swarm:latest
2)启动容器shipyard-proxy


docker run \
    -ti \
    -d \
    -p 2375:2375 \
    --hostname=$HOSTNAME \
    --restart=always \
    --name shipyard-proxy \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -e PORT=2375 \
    shipyard/docker-proxy:latest

3)启动容器shipyard-swarm-manager


docker run \
    -ti \
    -d \
    --restart=always \
    --name shipyard-swarm-manager \
    swarm:latest \
    manage --replication --addr 192.168.199.42:3375 --host tcp://0.0.0.0:3375 etcd://192.168.199.41:4001

4)启动容器shipyard-swarm-agent


docker run \
    -ti \
    -d \
    --restart=always \
    --name shipyard-swarm-agent \
    swarm:latest \
    join --addr 192.168.199.42:2375 etcd://192.168.199.41:4001

2016-01-22_22-49-38
查看容器shipyard-swarm-manager的log,看到已经注册
2016-01-22_21-04-51
5)Web界面访问。
还是访问http://192.168.199.41:8080,查看容器,已经多了节点docker42上的容器。
2016-01-22_21-06-18
查看节点,多了 docker42
2016-01-22_21-05-59
5.给节点设置label
为了分清节点的功能,我们分别给节点设置不同label,Shipyard好像取消了直接维护,我们只能在docker daemon设置。在docker41上修改。
vi /usr/lib/systemd/system/docker.service


ExecStart=/usr/bin/docker daemon -H unix:///var/run/docker.sock --label docker=dev

在docker42上修改。


ExecStart=/usr/bin/docker daemon -H unix:///var/run/docker.sock --label docker=online

分别重启docker,我们再看node节点label已改变。
2016-01-22_22-07-02
6.添加Mysql实例
1)添加Mysql-dev, 按图配置参数,端口,路径,容器名。swarm约束,我们选择标签为dev的那台。
2016-01-22_22-35-02
查看容器详细信息。
2016-01-22_22-38-36
2)添加Mysql-online,按图配置参数,端口,路径,容器名。swarm约束,我们选择标签为online的那台。
2016-01-22_22-37-33
查看容器详细信息。
2016-01-22_22-39-26
看到新增的两台容器,分别在不同的docker上。
2016-01-22_22-40-02
以上,我们看到Shipyard确实可以很方便的统一管理位于不同主机的容器。

PS.
启动从节点的容器shipyard-swarm-manager时,出现ID duplicated错误的解决办法。


ERRO[0008] ID duplicated. UGJV:S4FQ:NSHM:GL2I:OBON:UOJF:OZHB:E6FA:DVML:L67M:5ZLT:YM2G shared by 192.168.199.41:2375 and 192.168.199.42:2375

这个错误产生的原因,应该是安装docker后,我们两台主机是复制的,所以key值相同。
解决办法是,删除/etc/docker/key.json这个文件,重启docker。

参考:
https://docs.docker.com/swarm/multi-manager-setup/
https://shipyard-project.com/deploy
https://shipyard-project.com/docs/deploy/manual/

Tomcat详解

Tomcat(一):基础配置详解

简介:

Servlet(Server Applet),全称Java Servlet。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

Sun公司创建了第一个Servlet容器,即Java Web Server,但JWS只是为了演示Servlet的相应功能,所以其很不稳定。与此同时,Apache软件基金创建了JServ项目,一个能够与Apache整合起来的Servlet容器。1999年,Sun把JWS捐给了Apache软件基金,于是两个项目合二为一,即今天Tomcat的前身。第一个Tomcat版本是Tomcat 3.x系列,而发布于2001年Tomcat 4.0则是在此前基础上进行了重新设计和实现,其代码项目被命名为Catalina。

Tomcat是由Apache软件基金会下属的Jakarta项目开发的一个Servlet容器,按照Sun公司提供的技术规范,实现了对Servlet和JavaServer Page(JSP)的支持,并提供了作为Web服务器的一些特有功能,如Tomcat管理和控制平台、安全域管理和Tomcat阀等。由于Tomcat本身也内含了一个HTTP服务器,它也可以被视作一个单独的Web服务器。但是,不能将Tomcat和Apache Web服务器混淆,Apache Web Server是一个用C语言实现的HTTP web server;这两个HTTP web server不是捆绑在一起的。Apache Tomcat包含了一个配置管理工具,也可以通过编辑XML格式的配置文件来进行配置。

Tomcat提供了一个Jasper编译器用以将JSP编译成对应的Servlet。Tomcat的Servlet引擎通常与Apache或者其他Web服务器一起工作。除了用于开发过程中的调试以及那些对速度和事务处理只有很小要求的用户,很少会将Tomcat单独作为Web服务器。但随着版本的更新,正有越来越多的用户将其单独作为Web服务器用以那些对速度和可靠性有较高要求的环境中。

Tomcat不是一个完整意义上的Jave EE服务器,它甚至都没有提供对哪怕是一个主要Java EE API的实现;但由于遵守Apache开源协议,Tomcat却又为众多的Java应用程序服务器嵌入自己的产品中构建商业的Java应用程序服务器,如JBoss和JOnAS。尽管Tomcat对Jave EE API的实现并不完整,然而很企业也在渐渐抛弃使用传统的Java EE技术(如EJB)转而采用一些开源组件来构建复杂的应用。这些开源组件如Structs、Spring和Hibernate,而Tomcat能够对这些组件实现完美的支持。

HTTP是一种无状态的协议,在用户的一次连接请求响应完成后,服务器端将无法识别在后续的连接请求中再次识别此用户,交将其所有请求关联起来。为了解决这个问题,java container通过一个临时的cookie来为此用户保存一个标识,此标识即所谓的用户session。

在第一次调用之后,JSP会被编译成一个servlet类,在后续的操作中则可以直接使用此类,从而避免了对每一次调用的都要重新分析和编译。因此,类似servlet,JSP的执行需要在container中完成。JSP的container跟servlet的container基本相同,但在JSP执行之前,需要一些额外的步骤如与servlet代码建立会话等。Tomcat包含了一个叫做Catalina的Servlet container(执行servlet和编译过的JSP)和一个JSP编译器(Jasper编译器)。事实上,一个包含了JSP编译器和Servlet容器的应用程序组合通过被称作Web容器。

JSP和Servlet的最大区别在于,Servlet通常需要事先编译好,而JSP则并非必须事先编译。这意味着Servlet通常放置于私有资源区域,而JSP则通常以嵌入代码的方式包含于HTML页面文件中,这些HTML文件通常放置在公开资源区域。

MVC架构:Controller,Model和View各自独立,一个流行的开源实现是Apache Structs框架;目今,设计优良的Web应用程序通常用相就的技术实现相应的功能,比如: 1、Servlet用于实现应用逻辑; 2、JSP用于内容展示; 3、标签库和JSP扩展语言用于替换在JSP内部嵌入Java代码,进而降低了HTML维护的复杂度; 4、MVC框架用于实现展示和应用逻辑的分离;

安装tomcat:

先安装Jvm:

安装openjdk或oracle jdk:

1、安装openjdk:

[root@node0 ~]# yum install java-1.7.0-openjdk
[root@node0 ~]# java -version
java version "1.7.0_79"
OpenJDK Runtime Environment (rhel-2.5.5.4.el6-x86_64 u79-b14)
OpenJDK 64-Bit Server VM (build 24.79-b02, mixed mode)

2、安装oracle jdk: Jdk7下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html

[root@node0 ~]# yum install jdk-7u79-linux-x64.rpm
[root@node0 ~]# vim /etc/profile.d/java.sh
export JAVA_HOME=/usr/java/default
export PATH=$JAVA_HOME/bin:$PATH
[root@node0 java]# source /etc/profile.d/java.sh
[root@node0 java]# java -version
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)
安装tomcat:

官网:http://tomcat.apache.org

[root@node0 ~]# tar xf apache-tomcat-7.0.65.tar.gz -C /usr/local/
[root@node0 ~]# cd /usr/local/
[root@node0 local]# ln -sv apache-tomcat-7.0.65 tomcat
"tomcat" -> "apache-tomcat-7.0.65"
[root@node0 ~]# vim /etc/profile.d/tomcat.sh
export CATALINA_HOME=/usr/local/tomcat
export PATH=$CATALINA_HOME/bin:$PATH
[root@node0 ~]# source /etc/profile.d/tomcat.sh
提供脚本:
[root@node0 ~]# cat /etc/rc.d/init.d/tomcat
#!/bin/sh
# Tomcat init script for Linux.
#
# chkconfig: 2345 96 14
# description: The Apache Tomcat servlet/JSP container.
# JAVA_OPTS='-Xms64m -Xmx128m'
JAVA_HOME=/usr/lib/jvm/jre
CATALINA_HOME=/usr/local/tomcat
export JAVA_HOME CATALINA_HOME

case $1 in
start)
  exec $CATALINA_HOME/bin/catalina.sh start ;;
stop)
  exec $CATALINA_HOME/bin/catalina.sh stop;;
restart)
  $CATALINA_HOME/bin/catalina.sh stop
  sleep 2
  exec $CATALINA_HOME/bin/catalina.sh start ;;
*)
  echo "Usage: `basename $0` {start|stop|restart}"
  exit 1
  ;;
esac
[root@node0 ~]# chmod +x /etc/rc.d/init.d/tomcat
[root@node0 ~]# chkconfig tomcat --add

配置文件:

[root@node3 tomcat]# ls conf/    \\:Tomcat的配置文件;
server.xml:Tomcat的主配置文件,包含Service,Connector,Engine,Realm,Valve,Hosts主组件的相关配置信息;
web.xml:遵循Servlet规范标准的配置文件,用于配置servlet,并为所有的Web应用程序提供包括MIME映射等默认配置信息;
tomcat-user.xml:Realm认证时用到的相关角色、用户和密码等信息;Tomcat自带的manager默认情况下会用到此文件;在Tomcat中添加/删除用户,为用户指定角色等将通过编辑此文件实现;
catalina.policy:Java相关的安全策略配置文件,在系统资源级别上提供访问控制的能力;
catalina.properties:Tomcat内部package的定义及访问相关的控制,也包括对通过类装载器装载的内容的控制;Tomcat6在启动时会事先读取此文件的相关设置;
logging.properties:Tomcat通过自己内部实现的JAVA日志记录器来记录操作相关的日志,此文件即为日志记录器相关的配置信息,可以用来定义日志记录的组件级别以及日志文件的存在位置等;
    context.xml:每个webapp都有其配置文件,通常位于webapp目录下的WEB-INF目录中,通常用于定义会话管理器、Realm以及JDBC等;此配置文件是用于为部署在当前tomcat实例上的所有的webapp提供默认配置;
主配置文件:

组件:由java类实现;有些组件实现的方式不止一种;有些组件可以实现嵌套别的组件;由一组嵌套的层次和组件组成,一般可分为以下四类

顶级类组件:位于配置层次的顶级,并且彼此间有着严格的对应关系;

连接器组件:连接客户端(可以是浏览器或Web服务器)请求至Servlet容器,

容器类组件:包含一组其它组件;

被嵌套类组件:位于一个容器当中,但不能包含其它组件;

各常见组件:

1、服务器(server):Tomcat的一个实例,通常一个JVM只能包含一个Tomcat实例;因此,一台物理服务器上可以在启动多个JVM的情况下在每一个JVM中启动一个Tomcat实例,每个实例分属于一个独立的管理端口。这是一个顶级组件。

2、服务(service):一个服务组件通常包含一个引擎和与此引擎相关联的一个或多个连接器。给服务命名可以方便管理员在日志文件中识别不同服务产生的日志。一个server可以包含多个service组件,但通常情下只为一个service指派一个server。

连接器类组件:

3、连接器(connectors):负责连接客户端(可以是浏览器或Web服务器)请求至Servlet容器内的Web应用程序,通常指的是接收客户发来请求的位置及服务器端分配的端口。默认端口通常是HTTP协议的8080,管理员也可以根据自己的需要改变此端口。一个引擎可以配置多个连接器,但这些连接器必须使用不同的端口。默认的连接器是基于HTTP/1.1的Coyote。同时,Tomcat也支持AJP、JServ和JK2连接器。

容器类组件:

4、引擎(Engine):引擎通是指处理请求的Servlet引擎组件,即Catalina Servlet引擎,它检查每一个请求的HTTP首部信息以辨别此请求应该发往哪个host或context,并将请求处理后的结果返回的相应的客户端。严格意义上来说,容器不必非得通过引擎来实现,它也可以是只是一个容器。如果Tomcat被配置成为独立服务器,默认引擎就是已经定义好的引擎。而如果Tomcat被配置为Apache Web服务器的提供Servlet功能的后端,默认引擎将被忽略,因为Web服务器自身就能确定将用户请求发往何处。一个引擎可以包含多个host组件。

5、主机(Host):主机组件类似于Apache中的虚拟主机,但在Tomcat中只支持基于FQDN的“虚拟主机”。一个引擎至少要包含一个主机组件。

6、上下文(Context):Context组件是最内层次的组件,它表示Web应用程序本身。配置一个Context最主要的是指定Web应用程序的根目录,以便Servlet容器能够将用户请求发往正确的位置。Context组件也可包含自定义的错误页,以实现在用户访问发生错误时提供友好的提示信息。

被嵌套类(nested)组件:

这类组件通常包含于容器类组件中以提供具有管理功能的服务,它们不能包含其它组件,但有些却可以由不同层次的容器各自配置。

7、阀门(Valve):用来拦截请求并在将其转至目标之前进行某种处理操作,类似于Servlet规范中定义的过滤器。Valve可以定义在任何容器类的组件中。Valve常被用来记录客户端请求、客户端IP地址和服务器等信息,这种处理技术通常被称作请求转储(request dumping)。请求转储valve记录请求客户端请求数据包中的HTTP首部信息和cookie信息文件中,响应转储valve则记录响应数据包首部信息和cookie信息至文件中。

8、日志记录器(Logger):用于记录组件内部的状态信息,可被用于除Context之外的任何容器中。日志记录的功能可被继承,因此,一个引擎级别的Logger将会记录引擎内部所有组件相关的信息,除非某内部组件定义了自己的Logger组件。

9、领域(Realm):用于用户的认证和授权;在配置一个应用程序时,管理员可以为每个资源或资源组定义角色及权限,而这些访问控制功能的生效需要通过Realm来实现。Realm的认证可以基于文本文件、数据库表、LDAP服务等来实现。Realm的效用会遍及整个引擎或顶级容器,因此,一个容器内的所有应用程序将共享用户资源。同时,Realm可以被其所在组件的子组件继承,也可以被子组件中定义的Realm所覆盖。

应用部署:

tomcat的应用程序必须被“部署”才能够被访问:

部署:是指将webapp及其所依赖的类库等装载进tomcat实例,以便接收用户请求的操作过程;

部署方式:

静态方式(冷部署):在tomcat启动之前进行的部署;

动态方式(热部署):在不打断tomcat实例运行的前提下,通过tomcat manager或其它的部署工具进行的部署;

具体的部署工具:

Tomcat Manager

ANT脚本

TCD: tomcat client deployer

部署相关的操作:

Deploy:将webapp的源文件放置于目标目录、配置tomcat服务器能够基于context中定义的路径来访问此webapp,并将其特有的类通过class loader装载到tomcat实例上;

Redeploy:重新部署,常用于升级时;

Undeploy:反部署,停止webapp,并从tomcat实例移除其部分文件和部署名;

Stop:停止;

Start:启动

webapp应用程序:有多种归档格式

*.warweb应用程序
*.jarEJB类
*.rar:资源适配器
*.ear:企业级应用程序

对于一个Web应用程序而言,其通常由Servlets、JSP和其它文件等共同组成。这些文件通常被打包成WAR(Web Application Archive)格式,并以.war作为打包后的文件扩展名。而Servlet规范则定义了在WAR内部组织这些文件的标准目录结构。其目录和功用如下:

/:Web应用程序的根目录,所有可被公开访问的文件均放置于此处,如HTML、JSP和图片文件等;
/WEB-INF:此目录为私有资源目录,其内部的所有文件和子目录均不能被公开访问;包含着此Web应用程序的配置文件web.xml(程序结构描述符文件)通常放置于此目录;
/WEB-INF/classes:当前Web应用程序的类文件的存在目录;
/WEB-INF/lib:可被打包为JAR格式的类文件通常放置于此目录;

tomcat自带的两webapp:

manager:管理器

输出状态信息

部署webapp

host-manager:主机管理器

配置示例:

定义管理页面用户名及密码:

[root@node0 ~]# cd /usr/local/tomcat/conf
[root@node0 conf]# vim tomcat-users.xml
<role rolename="manager-gui"/>
  <role rolename="admin-gui"/>
  <user username="tomcat" password="tomcat" roles="manager-gui,admin-gui"/> 
[root@node0 conf]# service tomcat restart

访问测试:

输入用户名和密码:

输入图片说明

服务状态页:

输入图片说明

应用管理页:

输入图片说明

主机管理页:

输入图片说明

手动定义一个资源:

[root@node0 ~]# mkdir -p /tomcat/webapps/test/WEB-INF/{classess,lib}
[root@node0 ~]# cd /tomcat/webapps/test
[root@node0 app]# vim index.jsp
<%@ page language="java" %>
<html>
  <head><title>JSP Test Page</title></head>
  <body>
    <h1><font color="red">node0.chencer.org</font></h1>
    <table align="centre" border="1">
      <tr>
        <td>Session ID</td>
    <% session.setAttribute("chencer.org","chencer.org"); %>
        <td><%= session.getId() %></td>
      </tr>
      <tr>
        <td>Created on</td>
        <td><%= session.getCreationTime() %></td>
     </tr>
    </table>
  </body>
</html>

定义虚拟主机:

[root@node0 ~]# cd /usr/local/tomcat/conf
[root@node0 conf]# vim server.xml
<Engine name="Catalina" defaultHost="node0.chencer.org">    \\:默认主机设置为node0.chencer.org;

<Host name="node0.chencer.org" appBase="/tomcat/webapps" unpackWARs="true" autoDeploy="true">
</Host>

访问测试:

输入图片说明

实例:

部署站点程序;

站点程序包:JspRun!_6.0.0_GBK.zip

部署站点文件:

[root@node0 ~]# unzip JspRun\!_6.0.0_GBK.zip
[root@node0 ~]# mv upload /tomcat/webapps/jsprun
[root@node0 ~]# cd /tomcat/webapps/jsprun/
[root@node0 jsprun]# vim config.properties
dbhost = 192.168.1.4
dbport=3306
dbuser = jruser
dbpw = jrpass
dbname = jrdb

定义虚拟主机:

[root@node0 ~]# cd /usr/local/tomcat
[root@node0 tomcat]# vim conf/server.xml
<Host name="node0.chencer.org" appBase="/tomcat/webapps" unpackWARs="true" autoDeploy="true">
<Context path="/bbs" docBase="jsprun" />
</Host>

安装并启动mysql:

[root@node0 mysql-5.5-rpm]# yum install  MySQL-shared-compat-5.5.48-1.el6.x86_64.rpm MySQL-client-5.5.48-1.el6.x86_64.rpm MySQL-server-5.5.48-1.el6.x86_64.rpm
[root@node0 ~]# service mysql start

创建数据库,并赋予权限:

[root@node0 ~]# mysql
mysql> create database jrdb;
Query OK, 1 row affected (0.00 sec)
mysql> grant all on jrdb.* to 'jruser'@'192.168.1.4' identified by 'jrpass';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

站点安装:

输入图片说明

访问测试:

输入图片说明