作者:OceanBase高级技术专家神差
一、Proxy运行环境
obproxy运行环境:
OS: Linux Redhat 7u x86-64 及以上 CPU: 2 核及以上 内核:2.6.32 及以上版本 内存:1G 及以上 磁盘空间:对磁盘大小没有特别需求,根据数据和希望保留的日志大小决定 推荐 2G 及以上
二、Proxy命令行启动说明
obproxy在启动的时候,需要获悉rs_list等参数才可以正常启动,目前有两种方式。
第一种方式:启动的时候通过命令行指定rs_list参数,这种方式用于现阶段开发调试阶段,启动命令如下:
./bin/obproxy -p$port -r $ip:$port -e -n appname -o with_config_server=false -c 集群名
这种方式不需要额外配置。with_config_server=false,标示不依赖config server启动.
(注意: rslist方式只能访问单个集群,生产推荐使用config_server方式)
第二种方式:依赖config server启动,启动命令如下:
./bin/obproxy -p$port -e -n appname -o with_config_server=true,obproxy_config_server_url=http://xxxx:port/obproxy_config
这种启动方式不需要在命令行指定rs_list,但是需要配置config server。启动的时候需要把obproxy_config_server_url后面的地址替换成你的配置地址.
三、Proxy启动参数说明
./bin/obproxy -h ---------------------------------------------------------------------------------- obproxy [OPTIONS] -h,--help print this help -p,--listen_port LPORT obproxy listen port -o,--optstr OPTSTR extra options string -n,--appname APPNAME application name -c,--cluster_name CLUSTER_NAME root server cluster name -r,--rs_list RS_LIST root server list(format ip:sql_prot) -d,--dump_config_sql DSQL dump config sql to file -e,--execute_config_sql ESQL exectue config sql(create tables, insert initial data) -N,--nodaemon don't run in daemon -V,--obproxy_version VERSION current obproxy version example: run without config server: ./bin/obproxy -p$port -r'xxxx:port;xxxx:port' -n test -c njbank run with config server: ./bin/obproxy -p$port -o obproxy_config_server_url='your config url' -e -n test dump config update sql: ./bin/obproxy -d '' ----------------------------------------------------------------------------------
注:
- 启动命令中-p指定的端口是obproxy监听的端口,客户端通过mysql连接这个端口访问OB。只有第一次启动的时候需要指定这些参数,后续重启则不需要
- 启动命令中-e指定的建表操作,建议只在proxy第一次启动时进行,后续启动升级等均不要执行此命令
- 不依赖config server启动时, 传入的rs list中port是observe的sql port, 而不是rpc port
四、近端容器化部署
我们可以制作一个ODP的镜像,然后使用该镜像,在应用的容器中作为一个sidecar方式启动,下面介绍如何利用ObProxy的rpm包制作一个镜像并使用。
1. 制作镜像
准备文件
- 如果以 supervisord 方式启动,准备 supervisord 配置文件:obproxy.supervisord.conf。示例参见附录1
- 该文件仅用于 Docker 镜像内以 supervisord 方式启动obproxy_startup.sh文件,
- 启动脚本:obproxy_startup.sh,示例参见附录2
- 用于启动并守护 obproxy 进程
- OBProxy RPM包,需根据操作系统选择安装相应RPM包
- obproxy-${version}.el6.x86_64.rpm //适配6u机器
- obproxy-${version}.el7.x86_64.rpm //适配7u机器
其中version是版本号。
DockerFile编写
如果以supervisord方式启动,复制以下代码到DockerFile中,其中version以压缩包中rpm包版本号为准
ENV ADMIN_HOME=/home/admin
ENV OBPROXY_VERSION=xxx
ENV OBPROXY_ROOT=$ADMIN_HOME/obproxy-${OBPROXY_VERSION}
ENV OBPROXY_RPM=obproxy-${OBPROXY_VERSION}.rpm
RUN mkdir -p $ADMIN_HOME
RUN chown -R admin.admin $ADMIN_HOME
COPY ${OBPROXY_RPM} /tmp/${OBPROXY_RPM}
RUN cd /tmp && \
rpm2cpio ${OBPROXY_RPM} | cpio -id && \
mv opt/taobao/install/obproxy-${OBPROXY_VERSION} ${OBPROXY_ROOT}
RUN ln -s ${OBPROXY_ROOT} ${ADMIN_HOME}/obproxy
COPY obproxy.supervisord.conf /etc/supervisor/conf.d/
COPY obproxy_startup.sh ${OBPROXY_ROOT}/start_obproxy.sh
如果不以 supervisord 方式启动,复制以下代码,并按照业务自定义的启动方式,运行 obproxy_startup.sh 启动脚本(注意,obproxy 一定要先于应用启动)
ENV ADMIN_HOME=/home/admin
ENV OBPROXY_ROOT=$ADMIN_HOME/obproxy-${OBPROXY_VERSION}
ENV OBPROXY_VERSION=xxx
ENV OBPROXY_RPM=obproxy-${OBPROXY_VERSION}.rpm
RUN mkdir -p $ADMIN_HOME
RUN chown -R admin.admin $ADMIN_HOME
COPY ${OBPROXY_RPM} /tmp/${OBPROXY_RPM}
RUN cd /tmp && \
rpm2cpio ${OBPROXY_RPM} | cpio -id && \
mv opt/taobao/install/obproxy-${OBPROXY_VERSION} ${OBPROXY_ROOT}
COPY obproxy_startup.sh ${OBPROXY_ROOT}/start_obproxy.sh
2. 启动镜像
启动要求
- 设置环境变量(注意:每次启动均需要该变量)
- obproxy_config_server_url = xxx //OCP的地址
- (可选)obproxy_port = xxx //OBProxy的端口号,默认是2883
- (可选)obproxy_extra_opt=k=v,k=v... //obproxy配置参数
- 修改数据库链接地址。obproxy启动后,业务需要把数据库地址改成 127.0.0.1:2883。这个需要业务自行根据自己的方式修改
PS:不管什么方式,启动步骤都是上面这样,只不过不同平台,传递环境变量和调用启动脚本的方式不同
启动
以 docker run -e/--env-file 方式启动容器,传递 obproxy_config_server_url、obproxy_port、obproxy_extra_opt 等环境变量
3. 验证
OBProxy 端口是否开启
# 2883 由 ODP 开启,是 ODP 对外提供的 mysql 协议入口 $ netstat -an|grep 2883 tcp 0 0 0.0.0.0:2883 0.0.0.0:* LISTEN
验证数据库访问请求是否经过 ODP。
- 先确认业务是否访问到了本地 127.0.0.1:2883
- 验证业务访问 DB 是否正常
- 辅助验证,不一定有日志:
- 通过 ps -ax | grep obproxy 获取 obproxy 的 pid
- 查询 odp 的请求日志,验证数据库访问请求是否正常:
grep "${sql}" /home/admin/logs/obproxy/log/obproxy.${pid}.log中有经过 odp 的请求日志,数据库访问请求是否正常,可以查看经过 odp 的请求日志。
附录
附录1:obproxy.supervisord.conf 示例
[program:obproxy] command=bash /home/admin/obproxy/obproxy_startup.sh user=admin environment=HOME="/home/admin",USER="admin" startretries=0 autorestart=false priority=500
附录2:obproxy_startup.sh 示例
#!/bin/bash
OBPROXY_ROOT=$(dirname $(readlink -f "$0"))
function check_env()
{
if [ -z $OBPROXY_PORT ]
thenif [ ! -z $obproxy_port ]
then
OBPROXY_PORT=$obproxy_portelseecho "env OBPROXY_PORT not set, use default 2883"
OBPROXY_PORT=2883
fifiecho "obproxy listen port:$OBPROXY_PORT"
if [ -z $PROMETHEUS_PORT ]
thenif [ ! -z $prometheus_port ]
then
PROMETHEUS_PORT=$prometheus_portelseecho "env PROMETHEUS_PORT not set, use default 2884"
PROMETHEUS_PORT=2884
fifiecho "obproxy prometheus listen port:$PROMETHEUS_PORT"
if [ -z $APPNAME ]
then
if [ ! -z $appname ]
then
APPNAME=$appnameelse
echo "env APPNAME not set"
APPNAME="default"fifiecho "obproxy appname:$APPNAME"
if [ -z $IDCNAME ]
then
if [ ! -z $idcname ]
then
IDCNAME=$idcnameelse
echo "env IDCNAME not set"fifiecho "obproxy idcname:$IDCNAME"
if [ -z $ENABLE_ROOT_SERVER ]
then
if [ ! -z $enable_root_server ]
then
ENABLE_ROOT_SERVER=$enable_root_serverelse
echo "env ENABLE_ROOT_SERVER not set"fifiecho "obproxy enable_root_server:$ENABLE_ROOT_SERVER"
if [ -z $ROOT_SERVER_CLUSTER_NAME ]
then
if [ ! -z $root_server_cluster_name ]
then
ROOT_SERVER_CLUSTER_NAME=$root_server_cluster_nameelse
echo "env ROOT_SERVER_CLUSTER_NAME not set"fifiecho "obproxy root_server_cluster_name:$ROOT_SERVER_CLUSTER_NAME"
if [ -z $ROOT_SERVER_LIST ]
then
if [ ! -z $root_server_list ]
then
ROOT_SERVER_LIST=$root_server_listelse
echo "env ROOT_SERVER_LIST not set"fifiecho "obproxy root_server_list:$ROOT_SERVER_LIST"
if [ x$ENABLE_ROOT_SERVER == xtrue ];thenif [ -z $ROOT_SERVER_CLUSTER_NAME ]
thenecho "ROOT_SERVER_CLUSTER_NAME not set"exit 1
fi
if [ -z $ROOT_SERVER_LIST ]
thenecho "ROOT_SERVER_LIST not set"exit 1
fielseecho "use OBPROXY_CONFIG_SERVER_URL"if [ ! -z $OBPROXY_CONFIG_SERVER_URL ]
then
OBPROXY_CONFIG_SERVER_URL=$OBPROXY_CONFIG_SERVER_URLelse
OBPROXY_CONFIG_SERVER_URL=$obproxy_config_server_urlfiecho "obproxy config server url:$OBPROXY_CONFIG_SERVER_URL"fi
if [ -z $WORK_THREAD_NUM ]
then
if [ ! -z $work_thread_num ]
then
WORK_THREAD_NUM=$work_thread_numelse
echo "env WORK_THREAD_NUM not set, use default 8"
WORK_THREAD_NUM=8
fifiecho "obproxy work_thread_num:$WORK_THREAD_NUM"
if [ -z $OBPROXY_EXTRA_OPT ]
then
if [ ! -z $obproxy_extra_opt ]
then
OBPROXY_EXTRA_OPT=$obproxy_extra_optelse
echo "env OBPROXY_EXTRA_OPT not set"fifiecho "obproxy obproxy_extra_opt:$OBPROXY_EXTRA_OPT"
OBPROXY_OPT_LOCAL=",$OBPROXY_EXTRA_OPT"
}
function start()
{
cd $OBPROXY_ROOT;
while [ 1 ]
do
is_obproxy_exists
if [ $? -lt 1 ]
thenif [ x$ENABLE_ROOT_SERVER == xtrue ];then$OBPROXY_ROOT/bin/obproxy -p $OBPROXY_PORT -l $PROMETHEUS_PORT -n $APPNAME -c $ROOT_SERVER_CLUSTER_NAME -r "$ROOT_SERVER_LIST" -o enable_cached_server=false,enable_get_rslist_remote=true,monitor_stat_dump_interval='1s',enable_qos=true,enable_standby=false,query_digest_time_threshold='2ms',monitor_cost_ms_unit=true,enable_strict_kernel_release=false,enable_proxy_scramble=true,work_thread_num=$WORK_THREAD_NUM,proxy_mem_limited='2G',log_dir_size_threshold=10G,proxy_idc_name="$IDCNAME""$OBPROXY_OPT_LOCAL"else$OBPROXY_ROOT/bin/obproxy -p $OBPROXY_PORT -l $PROMETHEUS_PORT -n $APPNAME -o enable_cached_server=false,enable_get_rslist_remote=true,monitor_stat_dump_interval='1s',enable_qos=true,enable_standby=false,query_digest_time_threshold='2ms',monitor_cost_ms_unit=true,enable_strict_kernel_release=false,obproxy_config_server_url="$OBPROXY_CONFIG_SERVER_URL",enable_proxy_scramble=true,work_thread_num=$WORK_THREAD_NUM,proxy_mem_limited='2G',log_dir_size_threshold=10G,proxy_idc_name="$IDCNAME""$OBPROXY_OPT_LOCAL"fifi
sleep 10
done
}
function is_obproxy_exists()
{
process_count=`pgrep -x obproxy | wc -l`
return $process_count
}
check_env
start



