利用RHCS Nginx Fence實現高可用叢集部署
叢集概念
HA(High Available)高可用叢集是減少服務中斷時間為目的的伺服器叢集技術,也是保證業務連續性的有效解決方案。叢集,一般有兩個或者兩個以上的計算機組成,這些組成叢集的計算機被稱為節點。
其中由兩個節點組成的叢集被稱為雙機熱備,即使用兩臺伺服器互相備份,當其中一臺伺服器出現問題時,另一臺伺服器馬上接管服務,來保護使用者的業務程式對外不間斷提供的服務,當然集群系統更可以支援兩個以上的節點,提供比雙機熱備更多、更高階的功能,把因軟體/硬體/人為造成的故障對業務的影響降低到最小程度。
在叢集中為了防止伺服器出現“腦裂”的現象,叢集中一般會新增Fence裝置,有的是使用伺服器本身的的硬體介面稱為內部Fence,有的則是外部電源裝置稱為外部Fence,當一臺服務出現問題響應超時的時候,Fence裝置會對伺服器直接發出硬體管理指令,將伺服器重啟或關機,並向其他節點發出訊號接管服務。
在紅帽系統中我們通過luci和ricci來配置管理叢集,其中luci安裝在一臺獨立的計算機上或者節點上,luci只是用來通過web訪問來快速的配置管理叢集的,它的存在與否並不影響叢集。ricci是安裝在每個節點上,它是luci與叢集給節點通訊的橋樑。
Fence概念
在HA叢集壞境中,每個節點之間互相傳送探測包進行判斷節點的存活性。一般會有專門的線路進行探測,這條線路稱為“心跳線”。假設node1的心跳線出問題,則node2和node3會認為node1出問題,然後就會把資源排程在node2或者node3上執行,但node1會認為自己沒問題不讓node2或者node3搶佔資源,此時就出現了腦裂(split brain)。
此時如果在整個環境裡有一種裝置直接把node1斷電,則可以避免腦裂的發生,這種裝置叫做fence或者stonith(Shoot The Other Node In The Head爆頭哥)。
實驗前提
在server1與server4中配置高可用yum源
[rhel-source]
name=Red Hat Enterprise Linux $releasever - $basearch - Source
baseurl=http://172.25.14.250/source6.5
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
[LoadBalancer]
name=LoadBalancer
baseurl=http://172.25.14.250/source6.5/LoadBalancer
gpgcheck=0
[HighAvailability]
name=HighAvailability
baseurl=http://172.25.14.250/source6.5/HighAvailability
gpgcheck=0
[ResilientStorage]
name=ResilientStorage
baseurl=http://172.25.14.250/source6.5/ResilientStorage
gpgcheck=0
[ScalableFileSystem]
name=ScalableFileSystem
baseurl=http://172.25.14.250/source6.5/ScalableFileSystem
gpgcheck=0
主機解析:
[[email protected] ~]# vim /etc/hosts
172.25.14.100 www.westos.org
實驗:配置高可用叢集
在server1中:
[[email protected] ~]# yum install -y ricci luci
[[email protected] ~]# passwd ricci #設定密碼
Changing password for user ricci.
New password:
BAD PASSWORD: it is based on a dictionary word
BAD PASSWORD: is too simple
Retype new password:
passwd: all authentication tokens updated successfully.
[[email protected] ~]# /etc/init.d/ricci start
Starting system message bus: [ OK ]
Starting oddjobd: [ OK ]
generating SSL certificates... done
Generating NSS database... done
Starting ricci: [ OK ]
[[email protected] ~]# chkconfig ricci on ##開機自啟動
[[email protected] ~]# chkconfig luci on
[[email protected] ~]# /etc/init.d/luci start
Adding following auto-detected host IDs (IP addresses/domain names), corresponding to `server1' address, to the configuration of self-managed certificate `/var/lib/luci/etc/cacert.config' (you can change them by editing `/var/lib/luci/etc/cacert.config', removing the generated certificate `/var/lib/luci/certs/host.pem' and restarting luci):
(none suitable found, you can still do it manually as mentioned above)
Generating a 2048 bit RSA private key
writing new private key to '/var/lib/luci/certs/host.pem'
Start luci... [ OK ]
Point your web browser to https://server1:8084 (or equivalent) to access luci
#會自動生成一個地址https://server1:8084
在server4中:
[root@server4 ~]# yum install -y ricci
[root@server4 ~]# passwd ricci
[root@server4 ~]# /etc/init.d/ricci start
[root@server4 ~]# chkconfig ricci on
開啟firefox
web訪問luci配置叢集,https://server1:8084
username : root
Password : ##剛才設定的ricci的密碼
建立叢集並新增兩個節點
叢集新增成功
在server1中新增nginx指令碼
[[email protected] init.d]# vim nginx
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /usr/local/nginx/conf/nginx.conf
# pidfile: /usr/local/nginx/logs/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)
lockfile="/var/lock/subsys/nginx"
pidfile="/usr/local/nginx/logs/${prog}.pid"
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc -p $pidfile $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
configtest_q || return 6
stop
start
}
reload() {
configtest_q || return 6
echo -n $"Reloading $prog: "
killproc -p $pidfile $prog -HUP
echo
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
configtest_q() {
$nginx -t -q -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
# Upgrade the binary with no downtime.
upgrade() {
local oldbin_pidfile="${pidfile}.oldbin"
configtest_q || return 6
echo -n $"Upgrading $prog: "
killproc -p $pidfile $prog -USR2
retval=$?
sleep 1
if [[ -f ${oldbin_pidfile} && -f ${pidfile} ]]; then
killproc -p $oldbin_pidfile $prog -QUIT
success $"$prog online upgrade"
echo
return 0
else
failure $"$prog online upgrade"
echo
return 1
fi
}
# Tell nginx to reopen logs
reopen_logs() {
configtest_q || return 6
echo -n $"Reopening $prog logs: "
killproc -p $pidfile $prog -USR1
retval=$?
echo
return $retval
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest|reopen_logs)
$1
;;
force-reload|upgrade)
rh_status_q || exit 7
upgrade
;;
reload)
rh_status_q || exit 7
$1
;;
status|status_q)
rh_$1
;;
condrestart|try-restart)
rh_status_q || exit 7
restart
;;
*)
echo $"Usage: $0 {start|stop|reload|configtest|status|force-reload|upgrade|restart|reopen_logs}"
exit 2
esac
[[email protected] init.d]# chmod +x nginx
[[email protected] init.d]# /etc/init.d/nginx start
[[email protected] init.d]# /etc/init.d/nginx stop
[[email protected] init.d]# scp nginx server4:/etc/init.d/
在server4中:
[root@server4 init.d]# /etc/init.d/nginx start
[root@server4 init.d]# /etc/init.d/nginx stop
[root@server4 init.d]# /etc/init.d/nginx start
新增故障轉移域
Prioritized #設定優先順序,數字越小,優先順序越高
Restricted #設定只在勾選節點中執行
No Failback #設定當優先順序高的節點恢復時不會接管正在執行的服務
在Resource中新增資源,此處新增虛擬ip和httpd的指令碼(叢集要安裝httpd)
新增httpd指令碼
設定service group
Automatically Start This Service #設定自動開啟服務
Run Exclusive #設定當執行此服務時不再執行其他服務
點選Add Resource
先新增
再新增
測試:
在網頁上輸入172.25.14.100
測試:
檢視叢集狀態
在瀏覽器輸入www.westos.org
實現高可用,將nginx關閉,nginx轉移至server4
[root@server1 init.d]# /etc/init.d/nginx stop
clusvcadm管理叢集命令
[root@server1 init.d]# clusvcadm -d nginx #禁用服務
[root@server1 init.d]# clusvcadm -e nginx #開啟服務
[root@server1 init.d]# clusvcadm -r nginx -m server1 #將nginx轉移至server1執行
實驗:Fence機制
在物理機:
[[email protected] ~]# yum install fence-virtd-multicast.x86_64 fence-virtd-libvirt.x86_64 fence-virtd.x86_64 -y
[[email protected] ~]# fence_virtd -c #執行命令並按要求配置
Module search path [/usr/lib64/fence-virt]:
Available backends:
libvirt 0.1
Available listeners:
multicast 1.2
Listener modules are responsible for accepting requests
from fencing clients.
Listener module [multicast]:
The multicast listener module is designed for use environments
where the guests and hosts may communicate over a network using
multicast.
The multicast address is the address that a client will use to
send fencing requests to fence_virtd.
Multicast IP Address [225.0.0.12]:
Using ipv4 as family.
Multicast IP Port [1229]:
Setting a preferred interface causes fence_virtd to listen only
on that interface. Normally, it listens on all interfaces.
In environments where the virtual machines are using the host
machine as a gateway, this *must* be set (typically to virbr0).
Set to 'none' for no interface.
Interface [virbr0]: br0 #根據自己的網絡卡名進行設定
The key file is the shared key information which is used to
authenticate fencing requests. The contents of this file must
be distributed to each physical host and virtual machine within
a cluster.
Key File [/etc/cluster/fence_xvm.key]:
Backend modules are responsible for routing requests to
the appropriate hypervisor or management layer.
Backend module [libvirt]:
Configuration complete.
=== Begin Configuration ===
backends {
libvirt {
uri = "qemu:///system";
}
}
listeners {
multicast {
port = "1229";
family = "ipv4";
interface = "br0";
address = "225.0.0.12";
key_file = "/etc/cluster/fence_xvm.key";
}
}
fence_virtd {建立叢集並新增兩個節點
module_path = "/usr/lib64/fence-virt";
backend = "libvirt";
listener = "multicast";
}
=== End Configuration ===
Replace /etc/fence_virt.conf with the above [y/N]? y
[[email protected] ~]# systemctl restart fence_virtd
[[email protected] etc]# mkdir cluster
[[email protected] etc]# cd cluster/
[[email protected] cluster]# dd if=/dev/urandom of=fence_xvm.key bs=128 count=1 #採集隨即資訊到生成的key檔案裡
1+0 records in
1+0 records out
128 bytes (128 B) copied, 0.000176212 s, 726 kB/s
[[email protected] cluster]# ll fence_xvm.key
-rw-r--r-- 1 root root 128 Aug 2 14:05 fence_xvm.key
[[email protected] cluster]# systemctl restart fence_virtd #重新啟動fence_virtd服務
[[email protected] cluster]# scp fence_xvm.key [email protected]:/etc/cluster/ #將物理機產生的key檔案傳給server1
[[email protected] cluster]# scp fence_xvm.key [email protected]:/etc/cluster/ #將物理機產生的key檔案傳給server4
將Fence加入節點
Fence Devices設定:
將Fence Method加入節點
Nodes -> Add Fance Method
Add Fance Instance
檢視server4的UUID
在server1的節點中做相同操作
測試:
此時nginx在server1上執行
[root@server4 cluster]# fence_node server1 #會使server1重啟
server4會接管服務
實驗:資料儲存
實驗環境:
server1
server2
server4
在server2上面新加一塊硬碟,容量為8G
在server2中
[root@server2 ~]# yum install -y scsi-*
在serevr1中
[root@server1 ~]# yum install -y iscsi-*
在server4中
[root@server4 ~]# yum install -y iscsi-*
在server2中
[[email protected] ~]# vim /etc/tgt/targets.conf
38 <target iqn.2018-08.com.example:server.target1>
39 backing-store /dev/vdb
40 initiator-address 172.25.14.1
41 initiator-address 172.25.14.4
42 </target>
[[email protected] ~]# /etc/init.d/tgtd start
在server1
[root@server1 ~]# iscsiadm -m discovery -t st -p 172.25.14.2
[root@server1 ~]# iscsiadm -m node -l
在server4
[root@server4 ~]# iscsiadm -m discovery -t st -p 172.25.14.2
[root@server4 ~]# iscsiadm -m node -l
在server1中:
[root@server1 ~]# pvcreate /dev/sda
[root@server1 ~]# vgcreate clustervg /dev/sda
[root@server1 ~]# lvcreate -L 4G -n demo clustervg
在server4中
在server1上格式化lvm,停用nginx高可用:
[root@server1 ~]# mkfs.ext4 /dev/clustervg/demo
[root@server1 ~]# clusvcadm -d nginx
進入網頁luci介面 Server Group Delete刪除nginx:
之後到Resources的介面刪除nginx:
在server1中下載mysql mysql-server,在server4中下載mysql-server
在server1中
[root@server1 ~]# yum install -y mysql
[root@server1 ~]# yum install -y mysql-server
在server4中
[root@server4 ~]# yum install -y mysql-server
下載好之後,在server1中將剛才建立的lvm掛載到/var/lib/mysql目錄
[root@server1 mysql]# mount /dev/clustervg/demo /var/lib/mysql/
[root@server1 mysql]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/VolGroup-lv_root 19134332 1200024 16962328 7% /
tmpfs 251124 25656 225468 11% /dev/shm
/dev/vda1 495844 33487 436757 8% /boot
/dev/mapper/clustervg-demo 4128448 139256 3779480 4% /var/lib/mysql
[root@server1 mysql]# cd
[root@server1 ~]# chown mysql.mysql /var/lib/mysql/
[root@server1 ~]# ll -d /var/lib/mysql/
drwxr-xr-x 3 mysql mysql 4096 Aug 3 14:54 /var/lib/mysql/
[root@server1 ~]# /etc/init.d/mysqld start
[root@server1 ~]# cd -
/var/lib/mysql
[root@server1 mysql]# ls
ibdata1 ib_logfile0 ib_logfile1 lost+found mysql mysql.sock test
[root@server1 mysql]# cd
[root@server1 ~]# /etc/init.d/mysqld stop
[root@server1 ~]# umount /var/lib/mysql/
在server4中
[root@server4 ~]# mount /dev/clustervg/demo /var/lib/mysql/
[root@server4 ~]# ll -d /var/lib/mysql/
drwxr-xr-x 5 mysql mysql 4096 Aug 3 15:13 /var/lib/mysql/
[root@server4 ~]# cd /var/lib/mysql/
[root@server4 mysql]# ls
ibdata1 ib_logfile0 ib_logfile1 lost+found mysql test
[root@server4 mysql]# /etc/init.d/mysqld start
Starting mysqld: [ OK ]
[root@server4 mysql]# /etc/init.d/mysqld stop
Stopping mysqld: [ OK ]
[root@server4 mysql]# cd
[root@server4 ~]# umount /var/lib/mysql/
[root@server4 ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/VolGroup-lv_root 19134332 1133488 17028864 7% /
tmpfs 251124 25656 225468 11% /dev/shm
/dev/vda1 495844 33487 436757 8% /boot
進入網頁luci介面:在Resources中點選Add
再次點選Add,選擇script
再次點選Add
操作好上圖介面要寫的內容然後點選左下角Add Resource,分別新增172.25.6.100 mysqldata mysqld,然後submit.
在server1進入mysql檢視資料庫可以看待lost+found資料庫
更改檔案系統:
在server4中停用mysql高可用
[root@server4 ~]# clusvcadm -d mysql
進入到下圖介面:
點選Sever Group-> mysql-> filesystem,然後點選remove刪除,remove後點擊最下面的submit提交
進入Resources,刪除所選內容
在server1中:
[root@server1 ~]# mount /dev/clustervg/demo /var/lib/mysql/
[root@server1 ~]# lvextend -L +4G /dev/clustervg/demo
[root@server1 ~]# lvextend -l +1023 /dev/clustervg/demo
[root@server1 ~]# resize2fs /dev/clustervg/demo #對lvm做熱拉神
在server1中
[root@server1 ~]# lvremove /dev/clustervg/demo
[root@server1 ~]# lvcreate -L 4G -n demo clustervg
[root@server1 ~]# mkfs.gfs2 -j 3 -p lock_dlm -t westos_ha:mygfs2 /dev/clustervg/demo
[root@server1 ~]# mount /dev/clustervg/demo /var/lib/mysql/
[root@server1 ~]# cd /var/lib/mysql/
[root@server1 mysql]# chown mysql.mysql .
[root@server1 mysql]# ls
[root@server1 mysql]# ll -d
drwxr-xr-x 2 mysql mysql 3864 Aug 3 17:48 .
[root@server1 mysql]# /etc/init.d/mysqld start
在server4
[root@server4 mysql]# gfs2_tool sb /dev/clustervg/demo all
[root@server4 mysql]# gfs2_tool journals /dev/clustervg/demo
在server1和server4中關閉mysql
/etc/init.d/mysqld stop
在server1與server4中
[root@server1 ~]# vim /etc/fstab
在server1中:
[root@server1 ~]# clusvcadm -r mysql -m server4 #
測試:
在server1
在server4中可以看到passwd檔案
相關推薦
利用RHCS Nginx Fence實現高可用叢集部署
叢集概念 HA(High Available)高可用叢集是減少服務中斷時間為目的的伺服器叢集技術,也是保證業務連續性的有效解決方案。叢集,一般有兩個或者兩個以上的計算機組成,這些組成叢集的計算機被稱為節點。 其中由兩個節點組成的叢集被稱為雙機熱備,即使用兩臺
初識keepalived(三)——keepalived與nginx代理實現高可用
keepalived nginx 背景介紹nginx除了可以作為web服務器外,同時也是一個反向代理軟件,nginx不能完全取代apache,所以很多場景下nginx作為apache的反向代理服務器。nginx運行在用戶空間,代替用戶向服務器發起請求,請求返回時再經由nginx服務器返回給用戶。不同於
nginx+keepalived實現高可用負載均衡
其中 centos7.3 9.png IT 配置文件 bsp 是我 add nginx 環境: centos7.3虛擬機A 10.0.3.46 centos7.3虛擬機B 10.0.3.110 虛擬機A和B都需要安裝nginx和keepalived(過程省略,其中keepa
利用redis主從+keepalived實現高可用
linux 運維 redisRedis簡介: Redis是一個開源的使用ANSI C語言編寫、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API。從2010年3月15日起,Redis的開發工作由VMware主持。 redis是一個key-value存儲系統。和Memc
nginx+keepalive實現高可用負載均衡
keepalived+nginx高可實驗一:實驗環境 主nginx負載均衡器:192.168.10.63 (通過keepalived配置了VIP:192.168.10.188供外使用)副nginx負載均衡器:192.168.10.200(通過keepalived配置了VIP:192.168.10.188供外
nginx+keepalived實現高可用小型集群
MF 分享 bsp mas 1.5 構圖 type 啟動 master 1.利用keepalived實現nginx調度器高可用; 2.構建LNAMMP架構: 1) Nginx既是前端調度器,又是反向代理緩存服
LVS健康檢查及keepalived實現高可用叢集
LVS健康檢查 我們前面做的那些LVS的各種模式部署,都沒有健康檢查這一功能,就是說在我們搭建的負載均衡叢集中,如果後端伺服器RS全部宕掉了,客戶端就無法訪問到服務端的資料,這時我們應該給客戶端一些提示,說明伺服器暫時無法訪問。 配置(搭建好LVS-DR模式負載均衡的前提下) 在
Centos7上利用corosync+pacemaker+crmsh構建高可用叢集
一、高可用叢集框架 資源型別: primitive(native):表示主資源 group:表示組資源,組資源裡包含多個主資源 clone:表示克隆資源 masterslave:表示主從資源 資源約束方式: 位置約束:定義資源對節點的傾向性 排序約束:定義資源彼此能否執行在同一
CentOS7 haproxy+keepalived實現高可用叢集搭建
一、搭建環境 CentOS7 64位 Keepalived 1.3.5 Haproxy 1.5.18 後端負載主機:192.168.166.21 192.168.166.22 兩臺節點上安裝rabbitmq服務
nginx + keepalived實現高可用
1 MASTER 節點配置檔案(192.168.50.133) vi /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { ## keepalived 自帶的郵件提醒需要開啟
rabbitmq+haproxy+keepalived實現高可用叢集搭建
專案需要搭建rabbitmq的高可用叢集,最近在學習搭建過程,在這裡記錄下可以跟大家一起互相交流(這裡只是記錄了學習之後自己的搭建過程,許多原理的東西沒有細說)。 搭建環境 CentOS7 64位 RabbitMQ 3.6.2 Keepalived 1.2.21 主機:192.1
keepalived+nginx+mysql實現高可用及負載均衡
最近搗鼓了一下mysql資料庫的高可用方案。藉助mysql官方的InnoDB Cluster 以及nginx+keepalived。能夠輕易的做到。效果及穩定性令人滿意。 前言: 首先這裡預設你已
Keepalived+Tengine實現高可用叢集
概述 近年來隨著Nginx在國內的發展潮流,越來越多的網際網路公司使用Nginx;憑Nginx的高效能、穩定性等成為了眾多IT者青睞的WEB反向代理伺服器;但是Nginx雖然有很強大的代理功能,只有一臺Nginx伺服器難免不會出現問題,這就形成了單點故障的問題,而恰好可
MySQL+MMM 高可用叢集部署(一)
一、MMM的功能特點 MMM 即(Master-Master replication manager for MySQL)的簡稱,它是一套支援雙主故障切換和雙主日常管理的指令碼程式,而MMM是用 Perl 語言所開發,其主要功能是: 第一、用來監控和管理 MySQL 資料庫 主主複製(Master-M
MySQL+MMM 高可用叢集部署(二)
接上期,MySQL主從同步我們已經部署完成,接下來,我們開始部署本期的核心---MMM高可用叢集 四、MMM高可用叢集部署 1、安裝依賴包 由於mmm 是用perl語言寫的指令碼程式,因此需要在5臺伺
RabbitMQ高可用叢集部署及配置+HAproxy負載(原始碼)
1.環境 rabbitmq-1 10.24.43.4 centos6.x rabbitmq-2 10.24.43.5 centos6.x 2.
(十)RabbitMQ訊息佇列-高可用叢集部署實戰
前幾章講到RabbitMQ單主機模式的搭建和使用,我們在實際生產環境中出於對效能還有可用性的考慮會採用叢集的模式來部署RabbitMQ。 RabbitMQ叢集基本概念 Rabbit模式大概分為以下三種:單主機模式、普通叢集模式、映象叢集模式。 單主機模式:
SpringCloud元件:Eureka高可用叢集部署
高可用叢集部署 Eureka 服務註冊中心。 構建專案 使用 idea 開發工具建立一個 SpringBoot 專案,新增 Eureka Server 依賴即可, pom.xml 配置檔案如下所示: .
hadoop 2.7.2 + zookeeper 高可用叢集部署
一.環境說明 虛擬機器:vmware 11 作業系統:Ubuntu 16.04 Hadoop版本:2.7.2 Zookeeper版本:3.4.9 二.節點部署說明 三.Hosts增加配置 sudo gedit /etc/hosts wxzz-pc、wxzz-pc0、
hbase高可用叢集部署(cdh)
作者簡介:趙海軍 現就職於某創業公司任職運維兼DBA,曾就職於獵豹移動,負責資料庫團隊,運維前線作者之一。 一、概要 本文記錄hbase高可用叢集部署過程,在部署hbase之前需要事先部署好hadoop叢集,因為hbase的資料需要存放在hdfs上,hadoop叢集的部署後續會有一篇文章記錄,本文假