场景
防止由于停电后大规模 HV 启动, 导致 OPENSTACK NEUTRON SERVER 服务由于 HV 并发注册量太大而拒绝服务
思路
1. 数据库中创建表, COUNT, 列 id int 表中定义并发量, (例如 30)
2. 当 HV 启动时候, 假如需要启动 NEUTRON 服务, 则先要向 COUNT 表中获得信息,
假如 count.id 中值 > 1 , 则可以获得启动权限, 并 count.id -1,
当 neutron 服务注册完成, 则向数据库执行 count.id +1
参考表结构
用于做 bunket 算法
create table count ( id int ) engine innodb;
mysql> desc count;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
用于做数据记录的表, 可有可无
CREATE TABLE node (
id int(11) DEFAULT NULL,
name varchar(50) DEFAULT NULL
) ENGINE=InnoDB;
mysql> desc node;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(50) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
参考存储过程
获得 bunket 数据的存储过程
drop procedure startup;
delimiter //
create procedure startup( in d varchar(50), out n varchar(5) )
begin
declare a int;
declare b int;
declare c varchar(50);
select id into a from compute.count for update;
set autocommit=0;
if a > 0
then
select name into c from compute.node where name=d;
if c is null
then
set b=a-1;
insert into compute.node values ( a, d);
update compute.count set id=b;
set n='ready';
else
set n='faile';
end if;
end if;
commit;
select n from dual;
end
//
delimiter ;
完成neutron 注册后回调 bunket 的存储过程
drop procedure startend;
delimiter //
create procedure startend( in d varchar(50) )
begin
declare a int;
declare b int;
declare c varchar(50);
select id into a from compute.count for update;
set autocommit=0;
set b=a+1;
update compute.count set id=b;
delete from compute.node where name=d;
commit;
end
//
delimiter ;
参加 compute 节点启动时候的启动脚本
#!/bin/bash
#
#
source params <--- 注意: 公共变量, 公共函数存放的位置, 下文中缺的函数与变量都来自这里, 与整个算法无关, 忽略吧
service_type=compute
sqlstartpath='/root/manager/get_status.sql'
sqlendpath='/root/manager/end.sql'
status='faile'
if [ ! -d '/root/manager/' ]
then
mkdir -p '/root/manager'
fi
cat <<EOF > $sqlstartpath
set @a='ok';
use compute;
call startup('$hostname',@a);
EOF
cat <<EOF > $sqlendpath
use compute;
call startend('$hostname');
EOF
if [ ! -f "/usr/bin/mysql" ]
then
yum install -y mysql > /dev/null 2>&1
fi
while [ "$status" != "ready" ]
do
status=`mysql -h $sql_server -u $sql_user -p"$sql_passwd" --skip-column-names $sql_db -e "source $sqlstartpath;"`
if [ "$status" != "ready" ]
then
sleep 5
fi
done
start_server messagebus messagebus
start_server libvirtd libvirtd
start_server openstack-nova-compute nova_compute
start_server neutron-openvswitch-agent openvswitch_agent
start_server openvswitch openvswitch
start_server openstack-ceilometer-compute ceilometer_compute
mysql -h $sql_server -u $sql_user -p"$sql_passwd" --skip-column-names $sql_db -e "source $sqlendpath;"