iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >HBase如何启动脚本
  • 287
分享到

HBase如何启动脚本

2024-04-02 19:04:59 287人浏览 安东尼
摘要

这篇文章给大家分享的是有关HBase如何启动脚本的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。常用脚本主要包括:1、$HBASE_HOME/bin/start-hbase.sh&

这篇文章给大家分享的是有关HBase如何启动脚本的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

常用脚本主要包括:

1、$HBASE_HOME/bin/start-hbase.sh 

    启动整个集群

2、$HBASE_HOME/bin/stop-hbase.sh 

    停止整个集群

3、$HBASE_HOME/bin/hbase-daemons.sh

    启动或停止,所有的regionserver或ZooKeeper或backup-master

4、$HBASE_HOME/bin/hbase-daemon.sh

    启动或停止,单个master或regionserver或zookeeper

5、$HBASE_HOME/bin/hbase

    最终启动的实现由这个脚本执行

一般通过start-hbase.sh来启动HBase集群,脚本执行流程如下:

#!/usr/bin/env bash
# $? 最后运行的命令的结束代码
# $# 传shell给脚本的参数个数
# $0 shell脚本本身的名字
# $1 shell脚本的第一个参数
# $2 shell脚本的第二个参数
# $@ shell脚本的所有参数的列表
 
# Start hadoop hbase daemons.
# Run this on master node.
usage="Usage: start-hbase.sh"
 
bin=`dirname "${BASH_SOURCE-$0}"`
bin=`cd "$bin">/dev/null; pwd`
 
# 1、装载相关配置
. "$bin"/hbase-config.sh
 
# start hbase daemons
errCode=$? # 最后运行的命令的结束代码
if [ $errCode -ne 0 ] # 
then
  exit $errCode
fi
 
# 2、解析参数(0.96版本及以后才可以带唯一参数autorestart,作用就是重启) 
if [ "$1" = "autorestart" ] # 获取start-hbase.sh的参数,调用时未提供参数
then
  commandToRun="autorestart"
else 
  commandToRun="start"
fi
 
# HBASE-6504 - only take the first line of the output in case verbose GC is on
distMode=`$bin/hbase --config "$HBASE_CONF_DIR" org.apache.hadoop.hbase.util.HBaseConfTool 
hbase.cluster.distributed | head -n 1`
# 判定hbase是否为分布式模式,hbase-site.xml中配置的
 
# 3、调用相应的启动脚本
if [ "$distMode" == 'false' ] 
then
  "$bin"/hbase-daemon.sh --config "${HBASE_CONF_DIR}" $commandToRun master $@
else
  "$bin"/hbase-daemons.sh --config "${HBASE_CONF_DIR}" $commandToRun zookeeper
  "$bin"/hbase-daemon.sh --config "${HBASE_CONF_DIR}" $commandToRun master 
  "$bin"/hbase-daemons.sh --config "${HBASE_CONF_DIR}" --hosts "${HBASE_REGIONSERVERS}" $commandToRun regionserver
  "$bin"/hbase-daemons.sh --config "${HBASE_CONF_DIR}" --hosts "${HBASE_BACKUP_MASTERS}" $commandToRun master-backup
fi

hbase-config.sh的作用:

    装载相关配置,如HBASE_HOME目录、conf目录(HBASE_CONF_DIR)、regionserver机器列表(HBASE_REGIONSERVERS)、JAVA_HOME目录以及HBASE_BACKUP_MASTERS机器列表它会调用$HBASE_HOME/conf/hbase-env.sh。

if [ -z "$HBASE_ENV_INIT" ] && [ -f "${HBASE_CONF_DIR}/hbase-env.sh" ]; then
  . "${HBASE_CONF_DIR}/hbase-env.sh"
  export HBASE_ENV_INIT="true"
fi

hbase-env.sh的作用:

    主要是配置JVM及其GC参数,还可以配置log目录及参数,配置是否需要hbase管理ZK,配置进程id目录等。

# export JAVA_HOME=/usr/sca_app/java/jdk1.7.0
# Where log files are stored.  $HBASE_HOME/logs by default.
# export HBASE_LOG_DIR=${HBASE_HOME}/logs
# Tell HBase whether it should manage it's own instance of Zookeeper or not.
# export HBASE_MANAGES_ZK=true

hbase-daemons.sh的作用:

    根据需要启动的进程。

# Run a hbase command on all slave hosts.
# Modelled after $HADOOP_HOME/bin/hadoop-daemons.sh
 
usage="Usage: hbase-daemons.sh [--config <hbase-confdir>] \
 [--hosts regionserversfile] [start|stop] command args..."
 
# if no args specified, show usage
if [ $# -le 1 ]; then
  echo $usage
  exit 1
fi
 
bin=`dirname "${BASH_SOURCE-$0}"`
bin=`cd "$bin">/dev/null; pwd`
 
. $bin/hbase-config.sh
 
remote_cmd="cd ${HBASE_HOME}; $bin/hbase-daemon.sh --config ${HBASE_CONF_DIR} $@"
args="--hosts ${HBASE_REGIONSERVERS} --config ${HBASE_CONF_DIR} $remote_cmd"
 
command=$2
case $command in
  (zookeeper)
exec "$bin/zookeepers.sh" $args
;;
  (master-backup)
exec "$bin/master-backup.sh" $args
;;
  (*)
exec "$bin/regionservers.sh" $args
;;
esac

zookeepers.sh的作用:

    如果hbase-env.sh中的HBASE_MANAGES_ZK" = "true",那么通过ZKServerTool这个类解析xml配置文件,获取ZK节点列表(即hbase.zookeeper.quorum的配置值),然后通过ssh向这些节点发送远程命令:

cd ${HBASE_HOME};
$bin/hbase-daemon.sh --config ${HBASE_CONF_DIR} start/stop zookeeper 
if [ "$HBASE_MANAGES_ZK" = "true" ]; then
  hosts=`"$bin"/hbase org.apache.hadoop.hbase.zookeeper.ZKServerTool | grep '^ZK host:' | sed 's,^ZK host:,,'`
  cmd=$"${@// /\\ }"
  for zookeeper in $hosts; do
   ssh $HBASE_SSH_OPTS $zookeeper $cmd 2>&1 | sed "s/^/$zookeeper: /" &
   if [ "$HBASE_SLAVE_SLEEP" != "" ]; then
 sleep $HBASE_SLAVE_SLEEP
   fi
  done
fi

regionservers.sh的作用: 

    与zookeepers.sh类似,通过${HBASE_CONF_DIR}/regionservers配置文件,获取regionserver机器列表,然后SSH向这些机器发送远程命令:

cd ${HBASE_HOME};
$bin/hbase-daemon.sh --config ${HBASE_CONF_DIR} start/stop regionserver

master-backup.sh的作用: 

    通过${HBASE_CONF_DIR}/backup-masters这个配置文件,获取backup-masters机器列表(默认配置中,这个配置文件并不存在,所以不会启动backup-master),然后SSH向这些机器发送远程命令:

cd ${HBASE_HOME};
$bin/hbase-daemon.sh --config ${HBASE_CONF_DIR} start/stop master --backup

hbase-daemon.sh的作用:

    无论是zookeepers.sh还是regionservers.sh或是master-backup.sh,最终都会调用本地的hbase-daemon.sh,其执行过程如下: 

    1.运行hbase-config.sh,装载各种配置(java环境、log配置、进程ID目录等);

    2.指定文件的执行及日志输出路径;

# get arguments
startStop=$1
JAVA=$JAVA_HOME/bin/java
export HBASE_LOG_PREFIX=hbase-$HBASE_IDENT_STRING-$command-$HOSTNAME
export HBASE_LOGFILE=$HBASE_LOG_PREFIX.log
 
if [ -z "${HBASE_ROOT_LOGGER}" ]; then
export HBASE_ROOT_LOGGER=${HBASE_ROOT_LOGGER:-"INFO,RFA"}
fi
 
if [ -z "${HBASE_SECURITY_LOGGER}" ]; then 
export HBASE_SECURITY_LOGGER=${HBASE_SECURITY_LOGGER:-"INFO,RFAS"}
fi
 
loGout=$HBASE_LOG_DIR/$HBASE_LOG_PREFIX.out
loggc=$HBASE_LOG_DIR/$HBASE_LOG_PREFIX.gc
loglog="${HBASE_LOG_DIR}/${HBASE_LOGFILE}"
pid=$HBASE_PID_DIR/hbase-$HBASE_IDENT_STRING-$command.pid
export HBASE_ZNODE_FILE=$HBASE_PID_DIR/hbase-$HBASE_IDENT_STRING-$command.znode
export HBASE_START_FILE=$HBASE_PID_DIR/hbase-$HBASE_IDENT_STRING-$command.autorestart
# hbase0.98
# thiscmd=$0,表示该hbase-daemon.sh文件的绝对路径
# hbase1.0.1中如下,但是获取到的值与上面相同
thiscmd="$bin/$(basename ${BASH_SOURCE-$0})"
args=$@
 
case $startStop in
 
(start)
check_before_start
hbase_rotate_log $logout
hbase_rotate_log $loggc
echo starting $command, logging to $logout
# 如下命令会将internal_start作为参数再次传给hbase-daemon.sh脚本
nohup $thiscmd --config "${HBASE_CONF_DIR}" internal_start $command $args < /dev/null > ${logout} 2>&1  &
sleep 1; head "${logout}"
  ;;
 
(autorestart)
check_before_start
hbase_rotate_log $logout
hbase_rotate_log $loggc
nohup $thiscmd --config "${HBASE_CONF_DIR}" internal_autorestart $command $args < /dev/null > ${logout} 2>&1  &
  ;;
 
(internal_start)
# Add to the command log file vital stats on our environment.
echo "`date` Starting $command on `hostname`" >> $loglog
echo "`ulimit -a`" >> $loglog 2>&1
nice -n $HBASE_NICENESS "$HBASE_HOME"/bin/hbase \
--config "${HBASE_CONF_DIR}" \
$command "$@" start >> "$logout" 2>&1 &
echo $! > $pid
wait
cleanZNode
  ;;
 
(internal_autorestart)
touch "$HBASE_START_FILE"
#keep starting the command until asked to stop. Reloop on software crash
while true
  do
lastLaunchDate=`date +%s`
$thiscmd --config "${HBASE_CONF_DIR}" internal_start $command $args
 
#if the file does not exist it means that it was not stopped properly by the stop command
if [ ! -f "$HBASE_START_FILE" ]; then
  exit 1
fi
 
#if the cluster is being stopped then do not restart it again.
zparent=`$bin/hbase org.apache.hadoop.hbase.util.HBaseConfTool zookeeper.znode.parent`
if [ "$zparent" == "null" ]; then zparent="/hbase"; fi
zkrunning=`$bin/hbase org.apache.hadoop.hbase.util.HBaseConfTool zookeeper.znode.state`
if [ "$zkrunning" == "null" ]; then zkrunning="running"; fi
zkFullRunning=$zparent/$zkrunning
$bin/hbase zkcli stat $zkFullRunning 2>&1 | grep "Node does not exist"  1>/dev/null 2>&1
#grep returns 0 if it found something, 1 otherwise
if [ $? -eq 0 ]; then
  exit 1
fi
 
#If ZooKeeper cannot be found, then do not restart
$bin/hbase zkcli stat $zkFullRunning 2>&1 | grep Exception | grep ConnectionLoss  1>/dev/null 2>&1
if [ $? -eq 0 ]; then
  exit 1
fi
 
#if it was launched less than 5 minutes ago, then wait for 5 minutes before starting it again.
curDate=`date +%s`
limitDate=`expr $lastLaunchDate + 300`
if [ $limitDate -gt $curDate ]; then
  sleep 300
fi
  done
;;
 
(stop)
rm -f "$HBASE_START_FILE"
if [ -f $pid ]; then
  pidToKill=`cat $pid`
  # kill -0 == see if the PID exists
  if kill -0 $pidToKill > /dev/null 2>&1; then
echo -n stopping $command
echo "`date` Terminating $command" >> $loglog
kill $pidToKill > /dev/null 2>&1
waitForProcessEnd $pidToKill $command
  else
retval=$?
echo no $command to stop because kill -0 of pid $pidToKill failed with status $retval
  fi
else
  echo no $command to stop because no pid file $pid
fi
rm -f $pid
  ;;
 
(restart)
# stop the command
$thiscmd --config "${HBASE_CONF_DIR}" stop $command $args &
wait_until_done $!
# wait a user-specified sleep period
sp=${HBASE_RESTART_SLEEP:-3}
if [ $sp -gt 0 ]; then
  sleep $sp
fi
# start the command
$thiscmd --config "${HBASE_CONF_DIR}" start $command $args &
wait_until_done $!
  ;;
 
(*)
  echo $usage
  exit 1
  ;;
esac

    3.如果是start命令?

    滚动out输出文件,滚动gc日志文件,日志文件中输出启动时间+ulimit -a信息,如

“Mon Nov 26 10:31:42 CST 2012 Starting master on dwxx.yy.taobao”
"..open files                      (-n) 65536.."

    4.调用$HBASE_HOME/bin/hbase start master/regionserver/zookeeper

    5.执行wait,等待3中开启的进程结束

    6.执行cleanZNode,将regionserver在zk上登记的节点删除,这样做的目的是:在regionserver进程意外退出的情况下,可以免去3分钟的ZK心跳超时等待,直接由master进行宕机恢复 

    7.如果是stop命令?

    根据进程ID,检查进程是否存在;调用kill命令,然后等待到进程不存在为止

    8.如果是restart命令?

    调用stop后,再调用start。。。 

$HBASE_HOME/bin/hbase的作用:

    最终启动的实现由这个脚本执行。

    1.可以通过敲入$HBASE_HOME/bin/hbase查看其usage

[mvtech3@cu-dmz3 bin]$ hbase
Usage: hbase [<options>] <command> [<args>]
Options:
  --config DIR    Configuration direction to use. Default: ./conf
  --hosts HOSTS   Override the list in 'regionservers' file
 
Commands:
Some commands take arguments. Pass no args or -h for usage.
  shell           Run the HBase shell
  hbck            Run the hbase 'fsck' tool
  hlog            Write-ahead-log analyzer
  hfile           Store file analyzer
  zkcli           Run the ZooKeeper shell
  upgrade         Upgrade hbase
  master          Run an HBase HMaster node
  regionserver    Run an HBase HRegionServer node
  zookeeper       Run a Zookeeper server
  rest            Run an HBase REST server
  thrift          Run the HBase Thrift server
  thrift2         Run the HBase Thrift2 server
  clean           Run the HBase clean up script
  classpath       Dump hbase CLASSPATH
  mapredcp        Dump CLASSPATH entries required by mapReduce
  version         Print the version
  CLASSNAME       Run the class named CLASSNAME

    2.bin/hbase shell,这个就是常用的shell工具运维常用的DDL和DML都会通过此进行,其具体实现(对hbase的调用)是用ruby写的。

[mvtech3@cu-dmz3 bin]$ hbase shell
HBase Shell; enter 'help<RETURN>' for list of supported commands.
Type "exit<RETURN>" to leave the HBase Shell
Version 0.98.1-hadoop2, r1583035, Sat Mar 29 17:19:25 PDT 2014
 
hbase(main):001:0>

    3.bin/hbase hbck

    运维常用工具,检查集群的数据一致性状态,其执行是直接调org.apache.hadoop.hbase.util.HBaseFsck中的main函数。

    4.bin/hbase hlog

    log分析工具,其执行是直接调org.apache.hadoop.hbase.wal.WALPrettyPrinter中的main函数。    

    5.bin/hbase hfile

    hfile分析工具,其执行是直接调org.apache.hadoop.hbase.io.hfile.HFilePrettyPrinter中的main函数。

    6.bin/hbase zkcli

    查看/管理ZK的shell工具,其调用了org.apache.zookeeper.ZooKeeperMain的main函数。

    7.bin/hbase master、regionserver、zookeeper

$HBASE_HOME/bin/hbase start master/regionserver/zookeeper
其执行则直接调用
org.apache.hadoop.hbase.master.HMaster
org.apache.hadoop.hbase.regionserver.HRegionServer
org.apache.hadoop.hbase.zookeeper.HQuorumPeer
的main函数,而这些main函数就是了new一个了Runnable的HMaster/HRegionServer/QuorumPeer,在不停的Running...

    8.bin/hbase classpath 打印classpath

    9.bin/hbase version 打印hbase版本信息

    10.bin/hbase CLASSNAME

    所有实现了main函数的类都可以通过这个脚本来运行,比如前面的hlog hfile hbck工具,实质是对这个接口的一个快捷调用,而其他未提供快捷方式的class我们也可以用这个接口调用,如Region merge 调用:$HBASE_HOME/bin/hbase/org.apache.hadoop.hbase.util.Merge。

脚本使用小结:

    1.开启集群,start-hbase.sh

    2.关闭集群,stop-hbase.sh

    3.开启/关闭所有的regionserver、zookeeper

    hbase-daemons.sh start/stop regionserver/zookeeper

    4.开启/关闭单个regionserver、zookeeper

    hbase-daemon.sh start/stop regionserver/zookeeper

    5.开启/关闭master 

    hbase-daemon.sh start/stop master,是否成为active master取决于当前是否有active master。

感谢各位的阅读!关于“HBase如何启动脚本”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

您可能感兴趣的文档:

--结束END--

本文标题: HBase如何启动脚本

本文链接: https://www.lsjlt.com/news/64928.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • HBase如何启动脚本
    这篇文章给大家分享的是有关HBase如何启动脚本的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。常用脚本主要包括:1、$HBASE_HOME/bin/start-hbase.sh&...
    99+
    2024-04-02
  • 如何添加openSUSE启动脚本
    这篇文章给大家分享的是有关如何添加openSUSE启动脚本的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。openSUSE启动程序的设置比较特殊,以openSUSE 11为例。openSUSE的启动较分散,主要有/...
    99+
    2023-06-16
  • HBase如何增量备份的python脚本
    这篇文章将为大家详细讲解有关HBase如何增量备份的python脚本,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。  HBase自带的export/import机制可以实...
    99+
    2024-04-02
  • MySQL中如何实现service启动脚本
    这篇文章主要介绍了MySQL中如何实现service启动脚本,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 我们在搭建MySQL环境的时候...
    99+
    2024-04-02
  • real server中如何实现启动脚本
    这篇文章将为大家详细讲解有关real server中如何实现启动脚本,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。real server 的vip 启动脚本#!/bin/bash#chkconfig:&n...
    99+
    2023-06-09
  • 重写启动脚本
    !/bin/bash user=rootport=3306CmdPath=/opt/mysql/binpassword=xxxxxxxxxx base_dir=/opt/mysqlinst_dir=/dat...
    99+
    2024-04-02
  • php-fpm没有启动脚本如何解决
    本篇内容介绍了“php-fpm没有启动脚本如何解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!php-fpm启动脚本的方法:1、创建自启动...
    99+
    2023-07-04
  • 如何编写linux自动重启tomcat脚本
    这篇文章主要介绍“如何编写linux自动重启tomcat脚本”,在日常操作中,相信很多人在如何编写linux自动重启tomcat脚本问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何编写linux自动重启to...
    99+
    2023-06-09
  • centos/rhel如何实现nginx自启动脚本
    这篇文章主要介绍centos/rhel如何实现nginx自启动脚本,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!通常在centos、rhel的OS下,我们大多是通过chkconfig来管理服务,比如开机自动启动服务之...
    99+
    2023-06-09
  • mongodb服务启动脚本
    #!/bin/sh # #mongod - Startup script for mongod # # chkconfig: -&nbs...
    99+
    2024-04-02
  • hbase如何实现全备增量备份脚本
    小编给大家分享一下hbase如何实现全备增量备份脚本,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧![hadoop@robot-pbs-hadoop-master ...
    99+
    2023-06-03
  • php-fpm如何实现开机自动启动Shell脚本
    小编给大家分享一下php-fpm如何实现开机自动启动Shell脚本,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!网上有各种版本的php-fpm开机自动启动脚本, ...
    99+
    2023-06-09
  • Linux系统如何添加开机启动脚本
    这篇文章主要介绍Linux系统如何添加开机启动脚本,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. 编写脚本autostart.sh(这里以开机启动redis服务为例),脚本内容如下: #!/bin/sh...
    99+
    2023-06-28
  • 如何编写CentOS下redis自启动shell脚本
    这篇文章主要讲解了“如何编写CentOS下redis自启动shell脚本”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何编写CentOS下redis自启动shell脚本”吧!用这个脚本管理...
    99+
    2023-06-09
  • bat脚本启动Java服务
    bat脚本启动Java服务 1.终端cmd窗口运行jar2. bat脚本启动jar包3.后台启动bat脚本4. 运行bat只启动一次jar服务及停止脚本5.注意事项6.所用资源 1.终...
    99+
    2023-09-22
    java 开发语言 bat 脚本
  • linux怎么启动sh脚本
    要在Linux上启动一个.sh脚本,可以按照以下步骤操作: 打开终端。 导航到存储.sh脚本的目录。可以使用cd命令来进入目...
    99+
    2024-02-29
    linux
  • Shell脚本如何实现启动PHP内置FastCGI Server
    这篇文章主要介绍了Shell脚本如何实现启动PHP内置FastCGI Server,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前几天把工作平台从 Ubuntu 9.10 K...
    99+
    2023-06-09
  • Shell脚本如何控制docker容器启动顺序
    这篇文章将为大家详细讲解有关Shell脚本如何控制docker容器启动顺序,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.遇到的问题在分布式项目部署的过程中,经常要求服务器重启之后,应用(包括数据库)能...
    99+
    2023-06-07
  • Linux中如何自定义shell脚本启动jar包
    本篇内容主要讲解“Linux中如何自定义shell脚本启动jar包”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Linux中如何自定义shell脚本启动jar包”吧!一键启动、停止、重启 jav...
    99+
    2023-06-09
  • Linux如何配置开机自启动执行脚本
    这篇文章主要介绍了Linux如何配置开机自启动执行脚本,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。开机要启动的脚本qidong.sh [root@c69-01&n...
    99+
    2023-06-16
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作