LVS+Keepalived+httpd安装及配置
原文:http://blog.csdn.net/yanpenglei/article/details/53838354
环境
操作系统 CentOS-6.5-x86_64-minimal.iso
VIP:192.168.252.100
Director LVS-Master :192.168.252.10
Director LVS-Backup:192.168.252.11
Real Server 01:192.168.252.12
Real Server 02:192.168.252.13
安装 ipvsadm(分别在LVS-Master和LVS-Backup中)
linux内核2.4版本以上的基本都支持LVS,要使用lvs只需要再安装一个lvs的管理工具:ipvsadm
[root@souyunku ~]# yum install ipvsadm
##安装keepalived(分别在LVS-Master和LVS-Backup中)
keepalived配置
[root@souyunku ~]# yum install keepalived
备份 keepalived.conf
[root@souyunku ~]# cd /etc/keepalived/
[root@souyunku keepalived]# cp keepalived.conf keepalived.conf.bak
编辑 keepalived.conf
[root@souyunku ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
#指定keepalived在发生切换时需要发送email到的对象,一行一个
[email protected]
}
notification_email_from [email protected] #指定发件人
smtp_server localhost #指定smtp服务器地址
smtp_connect_timeout 30 #指定smtp连接超时时间
router_id LVS_DEVEL #运行keepalived机器的一个标识
}
vrrp_instance VI_1 { #监控多个网段的实例
#状态只有MASTER和BACKUP两种,并且要大写,MASTER为工作状态,BACKUP是备用状态。
state MASTER
interface eth0
#虚拟路由标识,同一个vrrp_instance的MASTER和BACKUP的vitrual_router_id 是一致的。
virtual_router_id 51
#优先级,同一个vrrp_instance的MASTER优先级必须比BACKUP高。
priority 100
#MASTER 与BACKUP 负载均衡器之间同步检查的时间间隔,单位为秒。
advert_int 1
authentication {
#验证authentication。包含验证类型和验证密码。类型主要有PASS、AH 两种,通常使用的类型为PASS
auth_type PASS
#据说AH 使用时有问题。验证密码为明文,同一vrrp 实例MASTER 与BACKUP 使用相同的密码才能正常通信
auth_pass 1111
}
# VIP
# ipvsadm -A -t 192.168.252.100:80 -s wlc
#虚拟ip地址,可以有多个地址,每个地址占一行
#同时这个ip 必须与我们在lvs 客户端设定的vip 相一致
virtual_ipaddress {
192.168.252.100/24
}
}
#虚拟IP,来源与上面的虚拟IP地址,后面加空格加端口号
virtual_server 192.168.252.100 80 {
delay_loop 6 #健康检查间隔,单位为秒
lb_algo rr #负载均衡调度算法,一般用wrr、rr、wlc
##负载均衡转发规则,一般包括:NAT(地址转换)、DR(直接路由)、TUN(隧道)
# DR轮询,调度器通过"轮叫"调度算法将外部请求按顺序轮流分配到集群中的真实服务器上
#它均等地对待每一台服务器,而不管服务器上实际的连接数和系统负载。
lb_kind DR
nat_mask 255.255.255.0
#会话保持时间,会话保持,就是把用户请求转发给同一个服务器
#不然刚在1上提交完帐号密码,就跳转到另一台服务器2上了
persistence_timeout 50
protocol TCP
#ipvsadm -a -t 192.168.252.100:80 -r 192.168.252.12:80 -g -w 1
#真实服务器,包括IP和端口号
real_server 192.168.252.12 80 {
#权重,数值越大,权重越高
weight 1
SSL_GET {
#检查url,可以指定多个
url {
path /
#检查的返回状态码
status_code 200
}
#连接超时时间
connect_timeout 2
#重连次数
nb_get_retry 2
#重连时间间隔
delay_before_retry 1
}
}
#ipvsadm -a -t 192.168.252.100:80 -r 192.168.252.12:80 -g -w 1
real_server 192.168.252.13 80{
weight 1
SSL_GET {
url {
path /
status_code 200
}
connect_timeout 2
nb_get_retry 2
delay_before_retry 1
}
}
}
我的 LVS-Master keepalived.conf 配置
LVS-Backup 配置文件中主要要修改的选项没有很多,有三个参数要注意
route_id XXX #MASTER和 BACKUP不同
** virtual_router_id 51** #同一个实例下,MASTER和BACKUP相同
** priority 90** #优先级,同一个实例下,MASTER高于BACKUP
! Configuration File for keepalived
global_defs {
notification_email {
[email protected]
[email protected]
[email protected]
}
notification_email_from [email protected]
smtp_server 192.168.252.100
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.252.100/24
}
}
virtual_server 192.168.252.100 80 {
delay_loop 6
lb_algo rr
lb_kind DR
nat_mask 255.255.255.0
persistence_timeout 50
protocol TCP
real_server 192.168.252.12 80 {
weight 1
SSL_GET {
url {
path /
status_code 200
}
connect_timeout 2
nb_get_retry 2
delay_before_retry 1
}
}
real_server 192.168.252.13 80{
weight 1
SSL_GET {
url {
path /
status_code 200
}
connect_timeout 2
nb_get_retry 2
delay_before_retry 1
}
}
}
分别在Rs 01,Rs 02 部署httpd服务并测试
Real Server 01:192.168.252.12
Real Server 02:192.168.252.13
分别在Rs 01,Rs 02 查看防火墙状态,如果是开启,就关闭
[root@souyunku ~]# service iptables status
[root@souyunku ~]# service iptables stop
iptables: Setting chains to policy ACCEPT: filter [ OK ]
iptables: Flushing firewall rules: [ OK ]
iptables: Unloading modules: [ OK ]
部署httpd服务
[root@souyunku ~]# yum install httpd
[root@souyunku ~]# service httpd start
Starting httpd: [ OK ]
测试httpd服务是否OK!
[root@souyunku ~]# echo "192.168.252.12">/var/www/html/index.html
[root@souyunku ~]# curl localhost
192.168.252.12
[root@souyunku ~]# curl 192.168.252.12
192.168.252.12
启动如果会报错
[root@souyunku ~]# service httpd start
Starting httpd: httpd: apr_sockaddr_info_get() failed for souyunku
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
修改主机名
[root@souyunku ~]# vi /etc/hosts
127.0.0.1 localhost.localdomain souyunku
#:::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
添加 DR模型调度的配置,分别在Rs 01,Rs 02 都配置
Real Server 01:192.168.252.12
Real Server 02:192.168.252.13
因为Keepalived配置的DR方式调度,需要修改,内核参数
让RealServer,以LVS的VIP来直接回复Client
用 lvsrs 脚本 一键配置,注意改VIP
root@souyunku ~] vi /etc/init.d/lvsrs
#!/bin/bash
#
# Script to start LVS DR real server.
# description: LVS DR real server
# . /etc/rc.d/init.d/functions
VIP=192.168.252.100
host=`/bin/hostname`
case "$1" in
start)
# Start LVS-DR real server on this machine.
/sbin/ifconfig lo down
/sbin/ifconfig lo up
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route add -host $VIP dev lo:0
;;
stop)
# Stop LVS-DR real server loopback device(s).
/sbin/ifconfig lo:0 down
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
;;
status)
# Status of LVS-DR real server.
islothere=`/sbin/ifconfig lo:0 | grep $VIP`
isrothere=`netstat -rn | grep "lo:0" | grep $VIP`
if [ ! "$islothere" -o ! "isrothere" ];then
# Either the route or the lo:0 device
# not found.
echo "LVS-DR real server Stopped."
else
echo "LVS-DR real server Running."
fi
;;
*)
# Invalid entry.
echo "$0: Usage: $0 {start|status|stop}"
exit 1
;; esac
启动 lvsrs 脚本,给脚本755权限
[root@souyunku ~]# chmod 755 /etc/init.d/lvsrs
[root@souyunku ~]# chmod 755 /etc/rc.d/init.d/functions
[root@souyunku ~]# service lvsrs start
分别在Rs 01,Rs 02 查看是否已有一个VIP地址
[root@souyunku ~]# ifconfig
eth0 ...
lo ...
lo:0 Link encap:Local Loopback
inet addr:192.168.252.100 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
把lvsrs服务添加到开机启动
把lvsrs服务添加到开机启动,否则下次启动电脑后,还需手动启动。
[root@souyunku ~]# echo "service lvsrs start" >> /etc/rc.local
分别在LVS-Master和LVS-Backup中 使用ipvsadm添加集群服务
[root@souyunku ~]# ipvsadm -C
[root@souyunku ~]# ipvsadm -L -n #查看ipvs定义的规则列表
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
[root@souyunku ~]#
[root@souyunku ~]# ipvsadm -A -t 192.168.252.100:80 -s wlc
[root@souyunku ~]# ipvsadm -a -t 192.168.252.100:80 -r 192.168.252.12:80 -g -w 1
[root@souyunku ~]# ipvsadm -a -t 192.168.252.100:80 -r 192.168.252.13:80 -g -w 1
[root@souyunku ~]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.252.100:80 wlc
-> 192.168.252.12:80 Route 1 0 0
-> 192.168.252.13:80 Route 1 0 0
查看Linux是否开启路由转发功能
[root@souyunku ~]# cat /proc/sys/net/ipv4/ip_forward
0
[root@souyunku ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
[root@souyunku ~]# cat /proc/sys/net/ipv4/ip_forward
1
###用 Director 脚本 一键配置 注意改VIP ,RIP1,RIP2
root@souyunku ~] vi /etc/init.d/DR
#!/bin/bash
#
# LVS script for VS/DR
# . /etc/rc.d/init.d/functions
VIP=192.168.252.100
RIP1=192.168.252.12
RIP2=192.168.252.13
PORT=80
case "$1" in
start)
/sbin/ifconfig eth0:0 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route add -host $VIP dev eth0:0
# Since this is the Director we must be able to forward packets
echo 1 > /proc/sys/net/ipv4/ip_forward
# Clear all iptables rules.
/sbin/iptables -F
# Reset iptables counters.
/sbin/iptables -Z
# Clear all ipvsadm rules/services.
/sbin/ipvsadm -C
# Add an IP virtual service for VIP 192.168.0.219 port 80
# In this recipe, we will use the round-robin scheduling method.
# In production, however, you should use a weighted, dynamic scheduling method.
/sbin/ipvsadm -A -t $VIP:80 -s wlc
# Now direct packets for this VIP to
# the real server IP (RIP) inside the cluster
/sbin/ipvsadm -a -t $VIP:80 -r $RIP1 -g -w 1
/sbin/ipvsadm -a -t $VIP:80 -r $RIP2 -g -w 1
/bin/touch /var/lock/subsys/ipvsadm &> /dev/null
;;
stop) # Stop forwarding packets
echo 0 > /proc/sys/net/ipv4/ip_forward
# Reset ipvsadm
/sbin/ipvsadm -C
# Bring down the VIP interface
/sbin/ifconfig eth0:0 down
/sbin/route del $VIP
/bin/rm -f /var/lock/subsys/ipvsadm
echo "ipvs is stopped..."
;;
status)
if [ ! -e /var/lock/subsys/ipvsadm ]; then
echo "ipvsadm is stopped ..."
else
echo "ipvs is running ..."
ipvsadm -L -n
fi
;;
*)
echo "Usage: $0 {start|stop|status}"
;; esac
启动 Director 脚本,给脚本755权限
[root@souyunku ~]# chmod 755 /etc/init.d/DR
[root@souyunku ~]# chmod 755 /etc/rc.d/init.d/functions
[root@souyunku ~]# service DR start
分别在LVS-Master和LVS-Backup中,启动keeplived服务,并检查是否生效
[root@souyunku ~]# service keepalived start
Starting keepalived: [ OK ]
[root@souyunku ~]# service DR start
[root@souyunku ~]#
[root@souyunku ~]## ipvsadm -L -n #查看ipvs规则是否生效
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.252.100:80 wlc
-> 192.168.252.12:80 Route 1 0 0
-> 192.168.252.13:80 Route 1 0 0
[root@souyunku ~]#
测试VIP,检查是否能主备切换。
查看主VIP
启动keeplived后,先用ip addr
显示主备服务器的VIP情况,当主备服务器同时启用keepalived时,只有主服务器拥有VIP地址,备服务器没有。
查看 LVS-Master 的 VIP
查看eth0: 下是有inet 192.168.252.100/24 scope global secondary eth0
[root@souyunku LVS-Master]# service keepalived start
[root@souyunku LVS-Master]# ip addr
1: lo: ...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:95:1a:59 brd ff:ff:ff:ff:ff:ff
inet 192.168.252.10/24 brd 192.168.252.255 scope global eth0
inet 192.168.252.100/24 scope global secondary eth0 #可以看到主服务器拥有VIP
inet6 fe80::20c:29ff:fe95:1a59/64 scope link
valid_lft forever preferred_lft forever
[root@souyunku init.d]#
LVS-Backup 看看有没有,结果证明是没有的
[root@souyunku LVS-Backup]# ip addr
1: ...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:d6:d3:f9 brd ff:ff:ff:ff:ff:ff
inet 192.168.252.11/24 brd 192.168.252.255 scope global eth0
inet6 fe80::20c:29ff:fed6:d3f9/64 scope link
valid_lft forever preferred_lft forever
[root@souyunku ~]#
停掉 LVS-Master 下 keepalived 服务
[root@souyunku LVS-Master ]# service keepalived stop
Stopping keepalived: [ OK ]
在 LVS-Backup 下 ip addr 看看有没有 vip
当停止主服务器的keepalived服务,再查看下主备服务器VIP地址,发现VIP> 地址已从主服务器转移到了备服务器;
[root@souyunku LVS-Backup ]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:d6:d3:f9 brd ff:ff:ff:ff:ff:ff
inet 192.168.252.11/24 brd 192.168.252.255 scope global eth0
inet 192.168.252.100/24 scope global secondary eth0#可以看到备服务器拥有VIP
inet6 fe80::20c:29ff:fed6:d3f9/64 scope link
valid_lft forever preferred_lft forever
[root@souyunku ~]#
启动 LVS-Master和LVS-Backup中,keeplived服务,启动添加 Director 脚本的集群服务(‘DR’ 是 Director 脚本的名称)
[root@souyunku LVS-Master]# service keepalived start
[root@souyunku LVS-Master]# service DR start
[root@souyunku LVS-Backup]# service keepalived start
[root@souyunku LVS-Master]# service DR start
负载均衡测试http页面
[root@souyunku ~]# curl http://192.168.252.100/index.html
192.168.252.13 #第 1 次是web 192.168.252.13
[root@souyunku ~]# curl http://192.168.252.100/index.html
192.168.252.12 #第 2 次是web 192.168.252.12
[root@souyunku ~]# curl http://192.168.252.100/index.html
192.168.252.13 #第 3 次是web 192.168.252.13
[root@souyunku ~]# curl http://192.168.252.100/index.html
192.168.252.12 #第 4 次是web 192.168.252.12
[root@souyunku ~]# curl http://192.168.252.100/index.html
192.168.252.13 #第 5 次是web 192.168.252.13
其他
负载均衡以及高可用测试
负载均衡测试
- 两台WEB服务器都工作正常,访问VIP地址时,可以被负载到两台WEB服务器上。
- 停掉一台WEB服务器的http服务后,访问VIP地址时,被负载到正常的WEB服务器上。
高可用测试
- 两台DR的keepalived服务器正常时,VIP地址在主服务器,提供正常服务
- 当关闭主服务器的keepalived后,VIP地址自动转移到备服务器上,当主服务器重启keepalived服务后,VIP自动转移回主服务器,备服务器继续备用,实现了高可用负载均衡。
其他常用操作
永久保存LVS规则并恢复
[root@souyunku ~]# service ipvsadm save
ipvsadm: Saving IPVS table to /etc/sysconfig/ipvsadm: [ OK ]
模拟清空ipvsadm规则来恢复
[root@souyunku ~]# ipvsadm -C
[root@souyunku ~]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
关闭LVS
在real服务器上执行
service lvsrs stop
LVS服务器上执行
service DR stop
ipvsadm -C
系统虚拟IP管理
查看虚拟IP地址 删除
ip address list
ip addr del 192.168.252.100 dev eth0
#或者
ifconfig lo:0 192.168.252.100 netmask 255.255.255.255 down
LVS 命令
[root@souyunku ~]# ipvsadm -help
ipvsadm v1.26 2008/5/15 (compiled with popt and IPVS v1.2.1)
Usage:
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask] [--pe persistence_engine]
ipvsadm -D -t|u|f service-address
ipvsadm -C
ipvsadm -R
ipvsadm -S [-n]
ipvsadm -a|e -t|u|f service-address -r server-address [options]
ipvsadm -d -t|u|f service-address -r server-address
ipvsadm -L|l [options]
ipvsadm -Z [-t|u|f service-address]
ipvsadm --set tcp tcpfin udp
ipvsadm --start-daemon state [--mcast-interface interface] [--syncid sid]
ipvsadm --stop-daemon state
ipvsadm -h
Commands:
Either long or short options are allowed.
--add-service -A add virtual service with options
--edit-service -E edit virtual service with options
--delete-service -D delete virtual service
--clear -C clear the whole table
--restore -R restore rules from stdin
--save -S save rules to stdout
--add-server -a add real server with options
--edit-server -e edit real server with options
--delete-server -d delete real server
--list -L|-l list the table
--zero -Z zero counters in a service or all services
--set tcp tcpfin udp set connection timeout values
--start-daemon start connection sync daemon
--stop-daemon stop connection sync daemon
--help -h display this help message
Options:
--tcp-service -t service-address service-address is host[:port]
--udp-service -u service-address service-address is host[:port]
--fwmark-service -f fwmark fwmark is an integer greater than zero
--ipv6 -6 fwmark entry uses IPv6
--scheduler -s scheduler one of rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,
the default scheduler is wlc.
--pe engine alternate persistence engine may be sip,
not set by default.
--persistent -p [timeout] persistent service
--netmask -M netmask persistent granularity mask
--real-server -r server-address server-address is host (and port)
--gatewaying -g gatewaying (direct routing) (default)
--ipip -i ipip encapsulation (tunneling)
--masquerading -m masquerading (NAT)
--weight -w weight capacity of real server
--u-threshold -x uthreshold upper threshold of connections
--l-threshold -y lthreshold lower threshold of connections
--mcast-interface interface multicast interface for connection sync
--syncid sid syncid for connection sync (default=255)
--connection -c output of current IPVS connections
--timeout output of timeout (tcp tcpfin udp)
--daemon output of daemon information
--stats output of statistics information
--rate output of rate information
--exact expand numbers (display exact values)
--thresholds output of thresholds information
--persistent-conn output of persistent connection info
--nosort disable sorting output of service/server entries
--sort does nothing, for backwards compatibility
--ops -o one-packet scheduling
--numeric -n numeric output of addresses and ports
[root@souyunku ~]#
ipvsadm有两种命令选项格式,长的和短的,具有相同的意思。在实际使用时,两种都可以。
-A –add-service 在内核的虚拟服务器表中添加一条新的虚拟服务器记录。也就是增加一台新的虚拟服务器。
-E –edit-service 编辑内核虚拟服务器表中的一条虚拟服务器记录。
-D –delete-service 删除内核虚拟服务器表中的一条虚拟服务器记录。
-C –clear 清除内核虚拟服务器表中的所有记录。
-R –restore 恢复虚拟服务器规则
-S –save 保存虚拟服务器规则,输出为-R 选项可读的格式
-a –add-server 在内核虚拟服务器表的一条记录里添加一条新的真实服务器记录。也就是在一个虚拟服务器中增加一台新的真实服务器
-e –edit-server 编辑一条虚拟服务器记录中的某条真实服务器记录
-d –delete-server 删除一条虚拟服务器记录中的某条真实服务器记录
-L|-l –list 显示内核虚拟服务器表
-Z –zero 虚拟服务表计数器清零(清空当前的连接数量等)
–set tcp tcpfin udp 设置连接超时值
–start-daemon 启动同步守护进程。他后面可以是master 或backup,用来说明LVS Router 是master 或是backup。在这个功能上也可以采用keepalived 的VRRP 功能。
–stop-daemon 停止同步守护进程
-h –help 显示帮助信息
其他的选项:
-t –tcp-service service-address 说明虚拟服务器提供的是tcp 的服务
[vip:port] or [real-server-ip:port]
-u –udp-service service-address 说明虚拟服务器提供的是udp 的服务
[vip:port] or [real-server-ip:port]
-f –fwmark-service fwmark 说明是经过iptables 标记过的服务类型。
-s –scheduler scheduler 使用的调度算法,有这样几个选项rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,默认的调度算法是: wlc.
-p –persistent [timeout] 持久稳固的服务。这个选项的意思是来自同一个客户的多次请求,将被同一台真实的服务器处理。timeout 的默认值为300 秒。
-M –netmask netmask persistent granularity mask
-r –real-server server-address 真实的服务器[Real-Server:port]
-g –gatewaying 指定LVS 的工作模式为直接路由模式(也是LVS 默认的模式)
-i –ipip 指定LVS 的工作模式为隧道模式
-m –masquerading 指定LVS 的工作模式为NAT 模式
-w –weight weight 真实服务器的权值
–mcast-interface interface 指定组播的同步接口
-c –connection 显示LVS 目前的连接 如:ipvsadm -L -c
–timeout 显示tcp tcpfin udp 的timeout 值 如:ipvsadm -L –timeout
–daemon 显示同步守护进程状态
–stats 显示统计信息
–rate 显示速率信息
–sort 对虚拟服务器和真实服务器排序输出
–numeric -n 输出IP 地址和端口的数字形式
** 参考网址**