Linux-HAproxy-高级功能及配置
基于cookie的会话保持
cookie value:为当前server指定cookie值,实现基于cookie的会话黏性,相对于基于 source 地址 hash 调度算法对客户端的粒度更精准,但同时也加大了haproxy负载,目前此模式使用较少, 已经被 session共享服务器代替
注意:不支持 tcp mode,使用 http mode
配置选项
cookie name [ rewrite | insert | prefix ][ indirect ] [ nocache ][ postonly ] [ preserve ][ httponly ] [ secure ][ domain ]* [ maxidle <idle> ][ maxlife ]
name: #cookie 的 key名称,用于实现持久连接 insert: #插入新的cookie,默认不插入cookie indirect: #如果客户端已经有cookie,则不会再发送cookie信息 nocache: #当client和hapoxy之间有缓存服务器(如:CDN)时,不允许中间缓存器缓存cookie,因为这会导致很多经过同一个CDN的请求都发送到同一台后端服务器
配置示例
listen web_port bind 10.0.0.7:80 balance roundrobin mode http #不支持 tcp mode log global cookie WEBSRV insert nocache indirect server web1 10.0.0.17:80 check inter 3000 fall 2 rise 5 cookie web1 server web2 10.0.0.27:80 check inter 3000 fall 2 rise 5 cookie web2
HAProxy状态页
通过web界面,显示当前HAProxy的运行状态
状态页配置项
stats enable #基于默认的参数启用stats page stats hide-version #将状态页中haproxy版本隐藏 stats refresh <delay> #设定自动刷新时间间隔,默认不自动刷新 stats uri <prefix> #自定义stats page uri,默认值:/haproxy?stats stats realm <realm> #账户认证时的提示信息,示例:stats realm HAProxy\ Statistics stats auth <user>:<passwd> #认证时的账号和密码,可定义多个用户,每行指定一个用户.默认:no authentication stats admin { if | unless } <cond> #启用stats page中的管理功能
启用状态页
listen stats bind :9999 stats enable #stats hide-version stats uri /haproxy-status #自定义stats page uri stats realm HAProxy\ Stats\ Page #账户认证时的提示信息 stats auth haadmin:123456 #两个用户 stats auth admin:123456 #stats refresh 30s stats admin if TRUE #安全原因,不建议打开
登录状态页
pid = 27134 (process #1, nbproc = 1, nbthread = 1) #pid为当前pid号,process为当前进程号,nbproc和nbthread为一共多少进程和每个进程多少个线程 uptime = 0d 0h00m04s #启动了多长时间 system limits: memmax = unlimited; ulimit-n = 200029 #系统资源限制:内存/最大打开文件数/ maxsock = 200029; maxconn = 100000; maxpipes = 0 #最大socket连接数/单进程最大连接数/最大管道数maxpipes current conns = 2; current pipes = 0/0; conn rate = 2/sec; bit rate = 0.000 kbps #当前连接数/当前管道数/当前连接速率 Running tasks: 1/14; idle = 100 % #运行的任务/当前空闲率 active UP: #在线服务器 backup UP: #标记为backup的服务器 active UP, going down: #监测未通过正在进入down过程 backup UP, going down: #备份服务器正在进入down过程 active DOWN, going up: #down的服务器正在进入up过程 backup DOWN, going up: #备份服务器正在进入up过程 active or backup DOWN: #在线的服务器或者是backup的服务器已经转换成了down状态 not checked: #标记为不监测的服务器 active or backup DOWN for maintenance (MAINT) #active或者backup服务器人为下线的 active or backup SOFT STOPPED for maintenance #active或者backup被人为软下线(人为将weight改成0)
IP透传
web服务器中需要记录客户端的真实IP地址,用于做访问统计、安全防护、行为分析、区域排行等场 景。
layer 4 与 layer 7
四层:IP+PORT转发
七层:协议+内容交换
四层负载
在四层负载设备中,把client发送的报文目标地址(原来是负载均衡设备的IP地址),根据均衡设备设置的 选择web服务器的规则选择对应的web服务器IP地址,这样client就可以直接跟此服务器建立TCP连接并 发送数据,而四层负载自身不参与建立连接,而和LVS不同,haproxy是伪四层负载均衡,因为haproxy 需要分别和前端客户端及后端服务器建立连接
七层代理
七层负载均衡服务器起了一个反向代理服务器的作用,服务器建立一次TCP连接要三次握手,而client要 访问Web Server要先与七层负载设备进行三次握手后建立TCP连接,把要访问的报文信息发送给七层负 载均衡;然后七层负载均衡再根据设置的均衡规则选择特定的 Web Server,然后通过三次握手与此台 Web Server建立TCP连接,然后Web Server把需要的数据发送给七层负载均衡设备,负载均衡设备再把 数据发送给client;所以,七层负载均衡设备起到了代理服务器的作用,七层代理需要和Client和后端服 务器分别建立连接
四层IP透传
#haproxy 配置: listen web_http_nodes bind 172.16.0.100:80 mode tcp #不支持http协议 balance roundrobin server web1 www.wangxiaochun.com:80 send-proxy check inter 3000 fall 3 rise 5 #添加send-proxy #nginx 配置:在访问日志中通过变量$proxy_protocol_addr 记录透传过来的客户端IP http { log_format main '$remote_addr - $remote_user [$time_local] "$request" "$proxy_protocol_addr"' server { listen 80 proxy_protocol; #启用此项,将无法直接访问此网站,只能通过四层代理访问 server_name www.wangxiaochun.com; ......
七层IP透传
当haproxy工作在七层的时候,也可以透传客户端真实IP至后端服务器
HAProxy配置
在由haproxy发往后端主机的请求报文中添加“X-Forwarded-For"首部,其值为前端客户端的地址;用于 向后端主发送真实的客户端IP
option forwardfor [ except <network> ] [ header <name> ] [ if-none ] [ except <network> ]:请求报请来自此处指定的网络时不予添加此首部,如haproxy自身所在网络 [ header <name> ]:使用自定义的首部名称,而非“X-Forwarded-For",示例:X-client [ if-none ] 如果没有首部才添加首部,如果有使用默认值
#haproxy 配置 defaults #此为默认值,首部字段默认为:X-Forwarded-For option forwardfor #或者自定义首部,如:X-client option forwardfor except 127.0.0.0/8 header X-client #listen配置 listen web_host bind 10.0.0.7:80 mode http log global balance random server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5 server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5
web服务器日志格式配置
#apache 配置: LogFormat "%{X-Forwarded-For}i %a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"% {User-Agent}i\"" combined #nginx 日志格式: $proxy_add_x_forwarded_for:包括客户端IP和中间经过的所有代理的IP $http_x_forwarded_For:只有客户端IP log_format main '"$proxy_add_x_forwarded_for" - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $http_x_forwarded_For';
[root@centos8 ~]#tail /var/log/nginx/access.log "172.16.0.200, 10.0.0.7" 10.0.0.7 - - [09/Apr/2020:19:10:16 +0800] "GET / HTTP/1.1" 200 4057 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2" "172.16.0.200"
#tomcat 配置:conf目录下的server.xml <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%{X-Forwarded-For}i %h %l %u %t "%r" %s %b" />
报文修改
在http模式下,基于实际需求修改客户端的请求报文与响应报文,通过reqadd和reqdel在请求报文添加 删除字段,通过rspadd与rspidel在响应报文中添加与删除字段。
注意:此功能的以下相关指令在2.1版本中已经取消
#在向后端服务器转发的请求报文尾部添加指定首部 reqadd <string> [{if | unless} <cond>] 示例:reqadd X-Via:\ HAproxy #注意只能有一个空格,并需要转义 #在向后端服务器转发的请求报文中删除匹配正则表达式的首部 reqdel <search> [{if | unless} <cond>] reqidel <search> [{if | unless} <cond>] #忽略大小写 示例: reqidel user-agent reqidel X-Forwarded-For #无法删除 #在向前端客户端转发的响应报文尾部添加指定首部 rspadd <string> [{if | unless} <cond>] 示例: rspadd X-Via:\ HAproxy rspadd Server:\ wanginx #从向前端客户端转发的响应报文中删除匹配正则表达式的首部 rspdel <search> [{if | unless} <cond>] rspidel <search> [{if | unless} <cond>] #忽略大小写 示例: rspidel ^server:.* #从响应报文删除server信息 rspidel X-Powered-By:.* #从响应报文删除X-Powered-By信息,一般此首部字段保存php版本信息 #
2.1版本以上用下面指令http-request和http-response代替
配置说明:
http-request add-header <name> <fmt> [ { if | unless } <condition> ] #示例:http-request add-header X-Haproxy-Current-Date %T
http-request del-header <name> [ { if | unless } <condition> ] http-response add-header <name> <fmt> [ { if | unless } <condition> ] http-response del-header <name> #示例:http-response del-header Server
范例:
#添加向后端报务器发起的请求报文首部 vim haproxy.cfg frontend main *:80 # bind *:80 default_backend websrvs reqadd testheader:\ haproxyserver #加此行,注意只能有一个空格,并需要转义 #在后端httpd服务器 vim /etc/httpd/conf/httpd.conf LogFormat "%{testheader}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{UserAgent}i\"" combined #查看日志 tail –f /var/log/httpd/acesss_log
范例:
#添加响应报文首部 vim haproxy.cfg frontend main *:80 # bind *:80 default_backend websrvs rspadd X-Via:\ HAproxy-1 #加此行 maxconn 5000 #客户端访问调试模式,查看reponse headers,看到 Server: Apache/2.4.37 (centos) #系统自带显示 X-Via: HAproxy-1 #删除响应报文中的server首部 vim haproxy.cfg frontend main *:80 # bind *:80 default_backend websrvs rspadd X-Via:\ HAproxy-1 rspdel Server 或者 rspidel server #加此行 ,忽略大小写 rspidel X-Powered-By:.* #删除Php版本 maxconn 5000 #客户端访问调试模式,查看reponse headers,看到 Server: Apache/2.4.37 (centos) #此行消失 X-Via: HAproxy-1 #增加响应报文的首部,实现伪装Server首部 vim haproxy.cfg frontend main *:80 # bind *:80 default_backend websrvs rspadd X-Via:\ HAproxy-1 rspdel Server #或者用 rspidel server rspadd Server:\ wanginx #增加此行 [root@internet ~]#curl -i 172.16.0.100 HTTP/1.1 200 OK date: Thu, 09 Apr 2020 08:32:10 GMT last-modified: Thu, 09 Apr 2020 01:23:18 GMT etag: "f-5a2d17630635b" accept-ranges: bytes content-length: 15 content-type: text/html; charset=UTF-8 server: wanginx RS1 10.0.0.17 [root@centos7 ~]#vim /etc/haproxy/haproxy.cfg listen web_port bind 10.0.0.7:80 http-request add-header X-Haproxy-Current-Date %T #添加首部 http-response del-header server #删除首部 mode http log global option httpchk http-check expect status 200 server web1 10.0.0.17:80 check inter 3000 fall 2 rise 5 server web2 10.0.0.27:80 check inter 3000 fall 2 rise 5 #查看后端服务器日志 tail –f /var/log/httpd/acesss_log 10.0.0.7 - - [05/Apr/2020:20:13:48 +0800] "GET / HTTP/1.1" 200 10 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) l ibcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2" "05/Apr/2020:12:13:48 +0000"
压缩功能
对响应给客户端的报文进行压缩,以节省网络带宽,但是会占用部分CPU性能
建议在后端服务器开启压缩功能,而非在HAProxy上开启压缩
配置选项
compression algo <algorithm> ... #启用http协议中的压缩机制,常用算法有 gzip,deflate #压缩算法<algorithm>支持下面类型: identity #debug调试使用的压缩方式 gzip #常用的压缩方式,与各浏览器兼容较好 deflate #有些浏览器不支持 raw-deflate #新式的压缩方式 compression type <mime type> ... #要压缩的文件类型 #示例: compression algo gzip deflate compression type text/html text/css text/plain
配置示例
listen web_host bind 10.0.0.7:80 mode http balance roundrobin log global option httplog compression algo gzip deflate #启用压缩和指定算法 compression type compression type text/plain text/html text/css text/xml text/javascript application/javascript #指定压缩文件类型 server web1 10.0.0.17:80 cookie web1 check inter 3000 fall 3 rise 5 server web2 10.0.0.27:80 cookie web2 check inter 3000 fall 3 rise 5 #后端服务器准备一个文本文件 [root@centos7 ~]#ll /var/www/html/m.txt -h -rwxr-xr-x 1 root root 772K Apr 2 12:56 /var/www/html/m.txt
web服务器状态监测
健康性检查的三种状态:仅限于web服务器(httpd)
三种状态监测方式
基于四层的传输端口做状态监测,此为默认方式
基于指定 URI 做状态监测,需要访问整个页面资源,占用更多带宽
基于指定 URI 的request请求头部内容做状态监测,占用较少带宽,建议使用此方式
基于应用层http协议进行健康性检测
基于应用层http协议,采有不同的监测方式,对后端real server进行状态监测
注意: 此方式会导致在后端服务器生成很多的HAProxy发起的访问日志
option httpchk #启用七层健康性检测,对tcp 和 http 模式都支持,默认为:OPTIONS / HTTP/1.0 option httpchk <uri> option httpchk <method> <uri> option httpchk <method> <uri> <version>
#期望以上检查得到的响应码 http-check expect [!] <match> <pattern> #示例: http-check expect status 200 http-check expect ! rstatus ^5 #支持正则表达式
#关于HTTP/1.1的说明 <version> is the optional HTTP version string. It defaults to "HTTP/1.0" but some servers might behave incorrectly in HTTP 1.0, so turning it to HTTP/1.1 may sometimes help. Note that the Host field is mandatory in HTTP/1.1, and as a trick, it is possible to pass it after "\r\n" following the version string.
配置示例
listen web_host bind 10.0.0.7:80 mode http balance roundrobin #option httpchk GET /monitor/check.html #默认HTTP/1.0 #option httpchk GET /monitor/check.html HTTP/1.0 #option httpchk GET /monitor/check.html HTTP/1.1 #注意:HTTP/1.1强制要求必须 有Host字段 option httpchk HEAD /monitor/check.html HTTP/1.1\r\nHost:\ 10.0.0.7 #使用HEAD减 少网络流量 cookie SERVER-COOKIE insert indirect nocache server web1 10.0.0.17:80 cookie web1 check inter 3000 fall 3 rise 5 server web2 10.0.0.27:80 cookie web2 check inter 3000 fall 3 rise 5 #在所有后端服务建立检测页面 [root@backend ~]#mkdir /var/www/html/monitor/ [root@backend ~]#echo monitor > /var/www/html/monitor/check.html
#关闭一台Backend服务器 [root@backend1 ~]#systemctl stop httpd
ACL
访问控制列表(ACL,Access Control Lists)是一种基于包过滤的访问控制技术,它可以根据设定的条 件对经过服务器传输的数据包进行过滤(条件匹配),即对接收到的报文进行匹配和过滤,基于请求报文头 部中的源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等信息内容进行匹配并执行 进一步操作,比如允许其通过或丢弃。
ACL配置选项
acl <aclname> <criterion> [flags] [operator] [<value>] acl 名称 匹配规范 匹配模式 具体操作符 操作对象类型
ACL-Name
acl image_service hdr_dom(host) -i img.magedu.com #ACL名称,可以使用大字母A-Z、小写字母a-z、数字0-9、冒号:、点.、中横线和下划线,并且严格区分大 小写,比如:my_acl和My_Acl就是两个完全不同的acl
ACL-criterion
定义ACL匹配规范,即:判断条件
hdr string,提取在一个HTTP请求报文的首部 hdr([<name> [,<occ>]]):完全匹配字符串,header的指定信息,<occ> 表示在多值中使用的值的出 现次数 hdr_beg([<name> [,<occ>]]):前缀匹配,header中指定匹配内容的begin hdr_end([<name> [,<occ>]]):后缀匹配,header中指定匹配内容end hdr_dom([<name> [,<occ>]]):域匹配,header中的domain name hdr_dir([<name> [,<occ>]]):路径匹配,header的uri路径 hdr_len([<name> [,<occ>]]):长度匹配,header的长度匹配 hdr_reg([<name> [,<occ>]]):正则表达式匹配,自定义表达式(regex)模糊匹配 hdr_sub([<name> [,<occ>]]):子串匹配,header中的uri模糊匹配 #示例: hdr(<string>) 用于测试请求头部首部指定内容 hdr_dom(host) 请求的host名称,如 www.magedu.com hdr_beg(host) 请求的host开头,如 www. img. video. download. ftp. hdr_end(host) 请求的host结尾,如 .com .net .cn
#示例: acl bad_agent hdr_sub(User-Agent) -i curl wget block if bad_agent
#有些功能是类似的,比如以下几个都是匹配用户请求报文中host的开头是不是www acl short_form hdr_beg(host) www. acl alternate1 hdr_beg(host) -m beg www. acl alternate2 hdr_dom(host) -m beg www. acl alternate3 hdr(host) -m beg www.
base : string #返回第一个主机头和请求的路径部分的连接,该请求从主机名开始,并在问号之前结束,对虚拟主机有用 <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag> base : exact string match base_beg : prefix match base_dir : subdir match base_dom : domain match base_end : suffix match base_len : length match base_reg : regex match base_sub : substring match
path : string #提取请求的URL路径,该路径从第一个斜杠开始,并在问号之前结束(无主机部分) <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag> path : exact string match path_beg : prefix match #请求的URL开头,如/static、/images、/img、/css path_end : suffix match #请求的URL中资源的结尾,如 .gif .png .css .js .jpg .jpeg path_dom : domain match path_dir : subdir match path_len : length match path_reg : regex match path_sub : substring match #示例: path_beg -i /haproxy-status/ path_end .jpg .jpeg .png .gif path_reg ^/images.*\.jpeg$ path_sub image path_dir jpegs path_dom magedu url : string #提取请求中的整个URL。一个典型的应用是具有预取能力的缓存,以及需要从数据库聚合多个信息并将它们保 存在缓存中的网页门户入口,推荐使用path url :exact string match url_beg : prefix match url_dir : subdir match url_dom : domain match url_end : suffix match url_len : length match url_reg : regex match url_sub : substring match dst #目标IP dst_port #目标PORT src #源IP src_port #源PORT
#示例: acl invalid_src src 10.0.0.7 192.168.1.0/24 acl invalid_src src 172.16.0.0/24 acl invalid_port src_port 0:1023 status : integer #返回在响应报文中的状态码
#七层协议 acl valid_method method GET HEAD http-request deny if ! valid_method
ACL-flags
ACL匹配模式
-i 不区分大小写 -m 使用指定的pattern匹配方法 -n 不做DNS解析 -u 禁止acl重名,否则多个同名ACL匹配或关系
ACL-operator
ACL 操作符
整数比较:eq、ge、gt、le、lt 字符比较: - exact match (-m str) :字符串必须完全匹配模式 - substring match (-m sub) :在提取的字符串中查找模式,如果其中任何一个被发现,ACL将匹配 - prefix match (-m beg) :在提取的字符串首部中查找模式,如果其中任何一个被发现,ACL将匹配 - suffix match (-m end) :将模式与提取字符串的尾部进行比较,如果其中任何一个匹配,则ACL进行匹配 - subdir match (-m dir) :查看提取出来的用斜线分隔(“/")的字符串,如其中任一个匹配,则ACL进行匹配 - domain match (-m dom) :查找提取的用点(“.")分隔字符串,如果其中任何一个匹配,则ACL进行匹配
ACL-value
value的类型 The ACL engine can match these types against patterns of the following types : - Boolean #布尔值 - integer or integer range #整数或整数范围,比如用于匹配端口范围 - IP address / network #IP地址或IP范围, 192.168.0.1 ,192.168.0.1/24 - string--> www.magedu.com exact #精确比较 substring #子串 suffix #后缀比较 prefix #前缀比较 subdir #路径, /wp-includes/js/jquery/jquery.js domain #域名,www.magedu.com - regular expression #正则表达式 - hex block #16进制
多个ACL的组合调用方式
多个ACL的逻辑处理
与:隐式(默认)使用
或:使用“or" 或 “||"表示
否定:使用 "!" 表示
多个ACL调用方式:
#示例: if valid_src valid_port #与关系,ACL中A和B都要满足为true,默认为与 if invalid_src || invalid_port #或,ACL中A或者B满足一个为true if ! invalid_src #非,取反,不满足ACL才为true
自定义HAProxy 错误界面
对指定的报错进行重定向,进行优雅的显示错误页面
使用errorfile和errorloc指令的两种方法,可以实现自定义各种错误页面
基于自定义的错误页面文件
#自定义错误页 errorfile <code> <file> <code> #HTTP status code.支持200, 400, 403, 405, 408, 425, 429, 500, 502,503,504 <file> #包含完整HTTP响应头的错误页文件的绝对路径。 建议后缀".http",以和一般的html文件相区分 #示例: errorfile 400 /etc/haproxy/errorfiles/400badreq.http errorfile 403 /etc/haproxy/errorfiles/403forbid.http errorfile 503 /etc/haproxy/errorfiles/503sorry.http
范例:
defaults #option forwardfor #no option http-use-htx 支持html文件,此设置和版本有关,2.1不支持 #...... #加下面行 errorfile 500 /usr/local/haproxy/html/500.http errorfile 502 /usr/local/haproxy/html/502.http errorfile 503 /usr/local/haproxy/html/503.http
范例:
[root@centos7 ~]#vim /etc/haproxy/haproxy.cfg defaults option http-keep-alive option forwardfor maxconn 100000 mode http timeout connect 300000ms timeout client 300000ms timeout server 300000ms errorfile 503 /apps/haproxy/html/503.http listen ....... [root@centos7 ~]#vim /apps/haproxy/html/503.http HTTP/1.1 503 Service Unavailable Content-Type:text/html;charset=utf-8 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>报错页面</title> </head> <body> <center><h1>网站维护中......请稍候再试</h1></center> <center><h2>联系电话:400-123-4567</h2></center> <center><h3>503 Service Unavailable</h3></center> </body> [root@centos7 ~]#systemctl restart haproxy #将后端服务器down,可以观察到以下页面
HAProxy 四层负载
针对除HTTP以外的TCP协议应用服务访问的应用场景
MySQL
Redis
Memcache
RabbitMQ
问题: 后端服务器和haproxy还是和客户端建立三次握手?
四层负载示例
注意:如果使用frontend和backend,一定在 frontend 和 backend 段中都指定mode tcp
listen redis-port bind 10.0.0.7:6379 mode tcp balance leastconn server server1 10.0.0.17:6379 check server server2 10.0.0.27:6379 check backup
范例:对 MySQL 服务实现四层负载
[root@centos7 ~]#vim /etc/haproxy/haproxy.cfg listen magedu_mysql bind 10.0.0.7:3306 mode tcp balance leastconn server mysql1 10.0.0.17:3306 check server mysql2 10.0.0.27:3306 check #如果不写端口号,可以转发,但无法 check状态 #或者使用frontend和backend实现 frontend mysql bind :3306 mode tcp #必须指定tcp模式 default_backend mysqlsrvs backend mysqlsrvs mode tcp #必须指定tcp模式 balance leastconn server mysql1 10.0.0.17:3306 server mysql2 10.0.0.27:3306 [root@centos7 ~]#systemctl restart haproxy #在后端服务器安装和配置mariadb服务 [root@centos7 ~]#yum -y install mariadb-server [root@centos7 ~]#mysql -e "grant all on *.* to test@'10.0.0.%' identified by '123456'" [root@centos7 ~]#vim /etc/my.cnf [mysqld] server-id=17 #在另一台主机为27 [root@centos7 ~]#systemctl start mariadb #测试 [root@centos6 ~]#mysql -utest -p123456 -e "show variables like 'hostname'" +---------------+--------------------------+ | Variable_name | Value | +---------------+--------------------------+ | hostname | centos17.wangxiaochu.com | +---------------+--------------------------+ [root@centos6 ~]#mysql -utest -p123456 -e "show variables like 'hostname'" +---------------+--------------------------+ | Variable_name | Value | +---------------+--------------------------+ | hostname | centos27.wangxiaochu.com | +---------------+--------------------------+ [root@centos6 ~]#mysql -utest -p123456 -h10.0.0.7 -e 'select @@server_id' +-------------+ | @@server_id | +-------------+ | 17 | +-------------+ [root@centos6 ~]#mysql -utest -p123456 -h10.0.0.7 -e 'select @@server_id' +-------------+ | @@server_id | +-------------+ | 27 | +-------------+