目录
1 Nginx概述
2 使用
3 反向代理
4 负载均衡
5 重写
6 Nginx的其他用法
7 一个HTTP到Nginx处理的过程
8 Nginx解决跨域问题
9 Nginx配置防盗链
10 对比F5参考资料
· GitHub
1 Nginx概述
1.1 概念
nginx是一款高性能的http服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。由俄罗斯的程序设计师Igor Sysoev所开发,官方测试nginx能够支支撑5万并发链接,并且cpu、内存等资源消耗却非常低,运行非常稳定,所以现在很多知名的公司都在使用nginx。
1.2 应用场景
(1)http服务器。Nginx是一个http服务可以独立提供http服务。可以做网页静态服务器。
(2)虚拟主机。可以实现在一台服务器虚拟出多个网站。例如个人网站使用的虚拟主机。
(3)反向代理,负载均衡。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。
1.3 原理
(1)nginx 是事件驱动的服务器。
(2)nginx 采用的是多进程,(每个进程都是)单线程。
(3)nginx 采用 IO 多路复用的事件模型。在Linux操作系统下,Nginx使用epoll事件模型(得益于此,Nginx在Linux操作系统下效率相当高)。在OpenBSD或FreeBSD操作系统上采用类似于epoll的事件模型kqueue。
Nginx 支持 select、poll、kqueue、epoll、rtsig 和 /dev/poll。当然,你不用特别指定事件模型,Nginx 会自动选择最佳。
epoll模型参考连接:select、poll和epoll模型 - 知乎
1.4 优缺点
(1)优点:
· 高性能
· 资源消耗低
· 模块化设计
· 模块编写简单
· 配置文件简洁
常见模块参考链接:Nginx常用模块及作用 - Room、C - 博客园
(2)缺点:( nginx 性能提升的代价是降低了其他方面)
· 稳定性,不如 apache 和 Windows Server 下的 Nginx
· 没有像 Apache 使用.htaccess 那样的访问设置
· 添加模块复杂(在版本 1.9.11 中增加了动态模块加载。但模块需要与 Nginx 同时编译)
1.5 nginx.conf配置文件
1.5.1 配置结构
events {
}
http {
server {}
}
1.5.2 指令
1.5.2.1 指令分类
① 简单指令 Simple Directives
如listen *:80;,是由 名称(listen)-参数(*:80)-分号(;) 构成。
简单指令只能包含在上下文指令中。(最高层的简单指令可以理解成在一个隐藏的上下文指令中)
② 上下文指令 Context Directives
如
server{
}
1.5.2.2 指令继承
指令总是向下继承,除非有内部重名的会覆盖外层。这跟编程语言变量作用域的规则一样。
1.5.2.3 一些具体指令
(1)worker_processes
· 格式:worker_processes 1;
· 指定工作进程数。推荐 auto,它会自动检测逻辑CPU内核数。如果 cpu 使用了超线程技术,例如双核4线程,可以设置为4。
· 拓展:
物理cpu数:主板上实际插入的cpu数量。
cpu核数:单块CPU上面能处理数据的芯片组的数量,如双核、四核等。
逻辑cpu数:一般情况下,逻辑cpu=物理CPU数×cpu核数。
(2)Events 上下文指令
· Events 这个上下文指令只能在配置文件里出现一次。
· 格式:
events{
worker_connections 512;
}
· worker_connections 单个工作进程可以允许同时建立连接的数量(此为调优的重要参数)。如果往上调整太多,记得有可能需要同时调整操作系统的最大打开文件数限制(ulimit)。
1.5.3 虚拟主机
虚拟主机是一种在单一主机或主机群上,实现多网域服务的方法,可以运行多个网站或服务的技术。常见有3种方法:
(1)基于IP地址。通过 listen 对应 IP,前提是你的主机得有多个 IP 地址,这个成本较大。
server {
listen 172.19.205.200:80;
}
server {
listen 172.19.205.201:80;
}
(2)基于端口号。通过 listen 对应端口,但一般网址都是默认 80/443,弄别的端口体验会很差。
server {
listen 80;
}
server {
listen 81;
}
(3) 基于主机名。通过 server_name,对应 HTTP 的 Host 头(对应一个IP地址)。HTTP1.1 新增 Host 头,用来填写主机名。
server {
listen 80;
server_name test1.xjnotxj.com;
}
server {
listen 80;
server_name test2.xjnotxj.com;
}
# 支持多个值
server_name example.com www.example.com;# 支持通配符
server_name example.com *.example.com www.example.*;
server_name ~^www[0-9]\.example\.com$;
· 3种方法的匹配规则
① default_server
server{
listen 80 default_server;
server_name foobar.com;
}
② 匹配规则
· 先匹配 listen
如果这都匹配不到,则根本就不会有响应,因为 HTTP 连接没法建立
· 然后匹配 server_name
· 准确值优先级大于通配符
· 如果没找到,有 default_server 则匹配
· 如果没有 default_server,就找第一个出现的 server
· 建议在负责兜底的匹配规则里:
· 首先有 default_server
· 然后 server_name 写成 _(只是惯例,你写成 @#$ 也没事,反正不会被匹配上),
·返回的话:
· 写上 return 444,这是 nginx 自己独有的 HTTP 响应码,含义是服务器不向客户端返回任何信息,并关闭连接(有助于恶意软件的威胁)。
· 可以重定向到你定制的错误页面或者官网首页。
1.5.4 Location Block
location 即 url 的匹配规则。
1.5.4.1 修饰符
· 先是最普通的写法:
location /api {} # 前缀匹配
· 然后支持上面表的修饰符
location = /api { } # 精确匹配
location ~ \.php$ { } # 正则匹配(区分大小写)
location ~* \.php$ { } # 正则匹配(不分大小写)
location ^~ /api { } # 非正则的前缀匹配
1.5.4.2 匹配
(1)匹配规则(按顺序依次匹配):
· 精确匹配 =
· 非正则的前缀匹配 ^~
· 正则匹配 ~ 和 ~*
· 前缀匹配
(2)注1:
· 一个网址中,域名不分大小写(例如 chrome 地址栏中输入大写,会自动变小写),但是后面的路径分大小写, nginx 也分。
· 注意有两种前缀匹配,且在这两种前缀匹配下,匹配越长优先级越高,与 location 所在位置的顺序无关
· 正则匹配如果匹配了多个,会选择出现顺序的首个,所以建议越精细的放的越靠前。
· 最终还是没找到,nginx 响应 404。
(2)注2:关于网址斜杠的问题
· 一个域名的最后一定要有一个斜杠,这是 RFC1738 规定的,如 https://www.baidu.com/ 是对的,而 https://www.baidu.com 不对,但日常大家都习惯不加,是因为如浏览器等都会帮我们自动加上。(对应 nginx 的精确匹配就是 location = / {})
· 一个网址(域名+路径)的最后的斜杠可有可没有。没有代表一个文件,有代表一个目录。
· 域名不看,nginx 只会把路径当成待比较的值,去参与上面介绍的匹配规则。(如 https://www.baidu.com/api/abc ,只会用 /api/abc 去参与匹配)
· nginx 用来匹配的路径,会忽略 ? 及后面。(如 https://www.baidu.com/api?param1¶m2,只会用 /api 去参与匹配)
1.5.4.3 Named Location Blocks
(1)Named Location 不能直接用于常规请求处理,并且永远不会与请求URI匹配。相反,它们只适用于内部重定向,搭配 try_files 指令。
try_files 指令检查是否存在所提供的文件名(按顺序检查,从左到右),try_files 的最后一个参数便是 Named Location。
try_files 是 nginx 在 0.7 以后的版本中加入的指令(放置在 server 或 location 块中),配合 Named Location,可以部分替代原本常用的 rewrite 。(rewrite 下面会详细介绍)
(2)使用:
location / {
try_files maintenance.html index.html @foobar;
}
location @foobar {
}
· try_files 不一定非要搭配 location,直接返回响应码也是可以的:
location / {
try_files maintenance.html index.html =404
}
(4)Location Block 内的指令
① 指定文件系统路径 —— root / alias
· root 指令:
location /foobar/resource_root {
root /etc/nginx/static/;
}
对 http://example.org/foobar/resource_root/b.jpg 的请求将解析为文件系统路径 /etc/nginx/static/foobar/resource_root/b.jpg。
原理:文件系统目录 = root + url_path(即 /etc/nginx/static/ + /foobar/resource_root/b.jpg = /etc/nginx/static//foobar/resource_root/b.jpg )
· alias 指令:
location /foobar/resource_alias {
alias /etc/nginx/static/;
}
对 https://xjnotxj.com/foobar/resource_alias/img/a.jpg 的请求将解析为文件系统路径 /etc/nginx/static/img/a.jpg。
原理:文件系统目录 = alias + (url_path - location)(即 /etc/nginx/static/ + /img/a.jpg = /etc/nginx/static//img/a.jpg )
注:上面的结果 /etc/nginx/static//img/a.jpg 注意中间是有两个斜杠。alias 路径最后的斜杠带不带要仔细考量,因为 (url_path - location) 的开头不一定有斜杠,最终结果不一定合法。
注:root 和 alias 还有一个区别,即:alias 只能位于 location 块中,而 root 可以在 location 块也可以在 server 块。(原因很简单,从它们两者的原理就可以看出,因为 alias 计算文件系统路径需要 location 的参与,而 root 不需要。)
② 指定网站默认页 —— index 指令
· 默认值:index index.html
· 原理:内部重定向【重点】
内部重定向即再一次搜索同一个 server 下的 location。
最早的时候这个文件被叫作“主页” (home page),意思就是当省略文件名时访问的那个默认的页面。随着 Web 的普及,这个词的意义似乎并没有被正确理解,现在不光是默认页面,似乎随便什么网页都可以被叫作主页了。
更多指令参考:Nginx 学习笔记 - 小蒋不素小蒋 - 博客园
1.6 进程模型
(1)master进程
· 接收来自外界的信号
· 向各worker进程发送信号
· 监控worker进程运行状态
· 当worker退出后,会自动重新启动新的worker进程
(2)worker进程
· 采用单线程,非阻塞的事件模型
· 监听端口及处理客户端请求
2 使用
2.1 静态访问
Web server很重要一部分工作就是提供静态页面的访问,例如images, html page。nginx可以通过不同的配置,根据request请求,从本地的目录提供不同的文件返回给客户端。
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
2.2 动态程序
2.2.1 CGI、FastCGI
(1)CGI(Common Gateway Interface,通用网关接口),是服务器与程序(或脚本)进行通信的接口。CGI 使程序员能够编写自己的动态 Web 应用程序。
(2)实现步骤:
· 一般通过 url 路径中的文件扩展名来进行判断是静态还是动态页面,例如将 .cgi、.php 等扩展名设置为动态页面。
· 接着通过配置 CGI / FastCGI 来运行程序,返回结果。
2.2.2 反向代理
3 反向代理
3.1 概念
(1)正向代理:类似于跳板机,代理访问外部资源,类似于海外代购
(2)反向代理:将请求转发(重新发起请求)给内部网络的服务器,对外表现为一个服务器(保证内网的安全,阻止web攻击),类似于明星经纪人
3.2 作用
(1)实现动态Web应用程序
(2)负载均衡
(3)保护服务器内网的真实IP地址
3.3 配置实例
(1)host文件
127.0.0.1 8080.qian.com
127.0.0.1 b8081.qian.com
(2)nginx.conf配置
server {
listen 80;
server_name 8080.qian.com;
location / {
proxy_pass http://127.0.0.1:8080;
index index.html index.html;
}
}
server {
listen 80;
server_name b8081.qian.com;
location / {
proxy_pass http://127.0.0.1:8081;
index index.html index.html;
}
}
4 负载均衡
4.1 概念
负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。
负载均衡,英文名称为Load Balance,其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务
4.2 分类
Nginx负载平衡实际上是反向代理的一种。
upstream 指令进行负载均衡配置。
4.2.1 HTTP 负载均衡
(1)默认算法:Round Robin(轮询)
http {
upstream ub {
server10.117.0.1:3010;
server10.117.0.2:3010;
server10.117.0.3:3010;
}server {
location / {
proxy_pass http://ub;
}
}
}
Round Robin(轮询)还可以加上服务器权重
http {
upstream ub {
server10.117.0.1:3010weight =5;
server10.117.0.2:3010weight =3;
server10.117.0.3:3010weight =1;
}server {
location / {
proxy_pass http://ub;
}
}
}
解释:服务器收到请求数的比重是 5:3:1
(2)Least Connections(最少连接数)
http {
upstream ub {
least_conn;
server 10.117.0.1:3010;
server 10.117.0.2:3010;
server 10.117.0.3:3010;
}server {
location / {
proxy_pass http://ub;
}
}
}
(3)Least Time(最短时间)【仅适用于 NGINX Plus】
http {
upstream ub {
hash $request_uri consistent;
server 10.117.0.1:3010;
server 10.117.0.2:3010;
server 10.117.0.3:3010;
}server {
location / {
proxy_pass http://ub;
}
}
}
注:肯定比上面的都好使,毕竟是 NGINX Plus 才有的收费功能。
(4)IP Hash(IP哈希)
http {
upstream ub {
ip_hash;
server10.117.0.1:3010;
server10.117.0.2:3010;
server10.117.0.3:3010;
}
server {
location / {
proxy_pass http://ub;
}
}
}
(5)Generic Hash(通用哈希)
http {
upstream ub {
hash $request_uri consistent;
server10.117.0.1:3010;
server10.117.0.2:3010;
server10.117.0.3:3010;
}
server {
location / {
proxy_pass http://ub;
}
}
}
解释:等于把上面 ip hash 变成了 $request_uri hash。
4.2.2 TCP 负载均衡
nginx 开源版 1.9.0 支持 TCP 负载平衡。
(1)写法
stream{
upstream backend{
server 127.0.0.1:8089;
server 127.0.0.2:1935;
server 127.0.0.3:1935;
}
server{
listen 80;
proxy_pass backend;
}
}
· 跟 HTTP 负载均衡写法的异同:
· stream block 取代 http block(stream 表示 TCP/UDP 流量)
· upstream 写法不变
· proxy_pass 属于 server 而不是 location,server 也不存在 location。
(2)优缺点
· 优点:性能好。直接转发原始TCP数据包,没有数据解析;如果是 HTTPS ,也免去了 SSL 层的损耗。
· 缺点:功能损失。例如无法通过 proxy_set_header 改写/注入 HTTP 标头
[拓展] 既然 proxy_set_header 无法用,那 TCP 代理怎么传递客户端的原始 IP 信息呢?
可以使用 proxy protocol。
proxy protocol 是 HAProxy 的作者 Willy Tarreau 于 2010 年开发和设计的一个 Internet 协议,通过为 tcp 添加一个很小的头信息,来方便的传递客户端信息(协议栈、源IP、目的IP、源端口、目的端口等)。其本质是在三次握手结束后由代理在连接中插入了一个携带了原始连接四元组信息的数据包。
具体例子参考:https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/
proxy protocol 也可以用在 HTTP 负载均衡上。
4.2.3 邮件协议的负载均衡
# 邮件流量
mail{}
4.3 宕机轮训配置规则
server {
listen 80;
server_name www.itmayiedu.com;
location / {
proxy_pass http://backserver;
index index.html index.htm;
proxy_connect_timeout 1;
proxy_send_timeout 1;
proxy_read_timeout 1;
}
}
5 重写
5.1 概念
rewrite 是 nginx 的重写模块,即ngx_http_rewrite_module。主要功能是改写请求URI,是Nginx默认安装的模块。rewrite模块会根据PCRE正则匹配重写URI,然后发起内部跳转再匹配location,或者直接做30x重定向返回客户端。
5.2 目的
· 通知用户他们正在请求的资源现在位于其他位置
· 控制处理流程等等
5.3 涉及命令
· return 和 rewrite,之前介绍的 try_files 也可以部分做到
· 重写模块同时也涉及了 break,if,set 等其它命令
5.4 return
(1)介绍
· 语法:
return URL; # 外部重定向
return code URL;
return code [text];
可以将 return 指令放置在 server 或 location 中。
(2)demo
return https: //baidu.com; # 默认 302
return 301 https: //baidu.com; # 必须是支持重定向的响应码,比如 200 就不行
return 200 "okokok"; # 修改不了响应行文本,原因未知
5.5 rewrite
(1)介绍
语法:rewrite regex replacement [flag];
可以将 rewrite 指令放置在 server 或 location 中。
(2)参数
① regex 为正则表达式
② flag 取值如下:
注意,rewrite 后 url 就会变了,下一个 rewrite 识别的就是改过的 url
③ replacement 为重写的值
如果 replacement 以协议头开头(如:http://,https:// 或 $scheme),则效果相当于 flag = redirect。
如果想在 replacement 中抛弃之前路径的请求参数,可以在最后加了个 ?,如
rewrite ^/users/(.*)$ /show?user=$1?
(3)demo
以 flag = 无 为例:
location / {
rewrite ^/user/(.*)$ /show/$1;
rewrite ^/show/(.*)$ /hide/$1;
}
location /show {
return200;
}
location /hide {
return201;
}
访问 https://example.com/user/a.jpg:
1、/user/a.jpg 被 location / 捕获
2、第一个 rewrite 把 /user/a.jpg 改写成 /show/a.jpg
注意,这时的路径已经被改写成 /show/a.jpg 了。
3、第二个 rewrite 把 /show/a.jpg 改写成 /hide/a.jpg
4、下面没有命令了,执行内部重定向
5、/hide/a.jpg 被 location /hide 捕获,返回 201
注:诸如 $1 和 $2 这种变量,表示正则表达式匹配的第 N 个参数.
(4)死循环
某些情况下,rewrite 重定向后,可能又会执行 rewrite,然后循环往复,进入死循环。
为了避免这种情况,nginx 会在循环 10 次时之后,直接返回 500 异常。
5.6 其他命令
(1)set —— 设置变量
set $var1 "hello world";
return 200 "response ok $var1";
(2)if —— 判断条件
if 比 rewrite 的正则匹配更灵活。
5.7 实例
注意:rewrite 因为有正则,所以比 return 更加影响性能(if 语句也如是),且可读性差,所以如果能用 return 就用 return。
(1)从旧网址重定向到新网址
server{
listen80;
listen 443 ssl;
server_name www.old-name.com old-name.com;
return 301 $scheme://www.new-name.com$request_uri;
# 不推荐
rewrite ^$scheme://www.new-name.com$request_uri permanent;
}
(2)强制所有请求使用 HTTPS
server{
listen 80;
server_name www.domain.com;
return 301 https://www.domain.com$request_uri;
# 不推荐
if($scheme!="https") {
rewrite ^ https://www.mydomain.com$request_uri permanent;
}
}
(3)添加/删除 www 前缀
# add 'www'
server{
listen 80;
listen 443 ssl;
server_name domain.com;
return 301 $scheme://www.domain.com$request_uri;
}
# remove 'www'
server{
listen 80;
listen 443 ssl;
server_name www.domain.com;
return 301 $scheme://domain.com$request_uri;
}
(4)兜底,把其它流量重定向到正确的域名 or 返回错误
server{
listen 80 default_server;
listen 443 ssl default_server;
server_name_;
return 301 $scheme://www.domain.com;
# or
return 444
}
6 Nginx的其他用法
6.1 nginx 禁止 / 允许某个(些) IP 访问
使用到 ngx_http_access_module 模块
deny,相反的为 allow
deny 1.1.1.1;
deny 8.0.0.0/8;
deny all
allow 1.1.1.1;
allow 8.0.0.0/8;
allow all; # default
原理:通过 $remote_addr 来判断。
在需要很多规则的情况下,最好使用 ngx_http_geo_module 模块。
结果:返回 403。
6.2 错误处理
error_page
(1)常见 HTTP (响应码)错误
· 403 Forbidden
· 404 Not Found
· 500 Internal Server Error 通常是 upstream server 返回的错误
· 502 Bad Gateway 通常是 nginx 无法到达 upstream server
· 503 Service Unavailable 通常是 nginx 因暂时超载或临时维护,无法处理HTTP请求
· 504 gateway timeout 通常是 upstream server 返回超时
(2)用法
error_page 可以位于 server block / location block
原理:通过内部重定向。(跟上面介绍的 index 指令 一样)
① 针对普通情况
基本:
# 指向错误页面
error_page 404/404.html;
error_page 500 502 503 504 /50x.html;
# 重定向到外部 url
error_page 500 http://www.google.com;
# 重定向到 named location block
location/ {
error_page 404= @fallback;
}
location @fallback{
proxy_pass http://different_backend;
}
注1:因为 error_page 是通过内部重定向,所以你可以显示地写一个与之对应的 location (如 location /404.html)来干更多事。
注2:因为 error_page 是通过内部重定向,所以 access 日志会有两条记录。
高级:
# 更改HTTP状态码(不推荐,这样 nginx 日志记录也是)error_page500=200/index.html
② 针对反向代理(使用 proxy_intercept_errors,error_page 才会生效)
location @rails {
proxy_pass http://rails_app;
proxy_intercept_errors on; # focus here
error_page 404/404.html;
}
7 一个HTTP到Nginx处理的过程
8 Nginx解决跨域问题
Tomcat同一个服务器,在jsp页面或其他java代码跳转页面时,域名必须相同(同一个web应用),用nginx搭建网关系统,可实现跨域跳转。
配置:
server {
listen 80;
server_name www.itmayiedu.com;
location /A {
proxy_pass http://a.a.com:81/A;
index index.html index.htm;
}
location /B {
proxy_pass http://b.b.com:81/B;
index index.html index.htm;
}
}
9 Nginx配置防盗链
设置可以访问固定后缀静态资源的域名
location ~ .*\.(jpg|jpeg|JPG|png|gif|icon)$ {
valid_referers blocked http://www.itmayiedu.com www.itmayiedu.com;
if ($invalid_referer) {
return 403;
}
}
10 对比F5
10.1 F5的负载均衡功能
其实看到Nginx的原理和功能,是不是觉得已经不需要F5了?当然也不是,F5毕竟是负载均衡的老前辈,一直以来都以功能强大,性能稳定著称,很多功能其实是软负载无法做到的。
F5 BIG-IP用作HTTP负载均衡器的主要功能:
(1)F5 BIG-IP提供12种灵活的算法将所有流量均衡的分配到各个服务器,而面对用户,只是一台虚拟服务器。
(2)F5 BIG-IP可以确认应用程序能否对请求返回对应的数据。假如F5 BIG-IP后面的某一台服务器发生服务停止、死机等故障,F5会检查出来并将该服务器标识为宕机,从而不将用户的访问请求传送到该台发生故障的服务器上。这样,只要其它的服务器正常,用户的访问就不会受到影响。宕机一旦修复,F5 BIG-IP就会自动查证应用保证对客户的请求作出正确响应并恢复向该服务器传送。
(3)F5 BIG-IP具有动态Session的会话保持功能,笔者也是在网站中使用的F5将用户IP与Session通过F5进行的绑定,使其Session保持一致。
(4)F5 BIG-IP的iRules功能可以做HTTP内容过滤,根据不同的域名、URL,将访问请求传送到不同的服务器。
10.2 对比
(1)F5,硬件
优点:能够直接通过智能交换机实现,处理能力更强,而且与系统无关,负载性能强,更适用于一大堆设备、大访问量、简单应用。
缺点:成本高,除设备价格高昂,而且配置冗余,很难想象后面服务器做一个集群,但最关键的负载均衡设备却是单点配置,无法有效掌握服务器及应用状态。
硬件负载均衡,一般都不管实际系统与应用的状态,而只是从网络层来判断,所以有时候系统处理能力已经不行了,但网络可能还来得及反应(这种情况非常典型,比如应用服务器后面内存已经占用很多,但还没有彻底不行,如果网络传输量不大就未必在网络层能反映出来)
(2)Nginx,软负载
优点:基于系统与应用的负载均衡,能够更好地根据系统与应用的状况来分配负载。这对于复杂应用是很重要的,性价比高,实际上如果几台服务器,用F5之类的硬件产品显得有些浪费,而用软件就要合算得多,因为服务器同时还可以跑应用、做集群等。