千家信息网

MYSQL架构中如何主从MHA

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章给大家介绍MYSQL架构中如何主从MHA,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。MHA - GTID模式MasterHigh Availability Manage
千家信息网最后更新 2026年11月02日MYSQL架构中如何主从MHA

这篇文章给大家介绍MYSQL架构中如何主从MHA,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

MHA - GTID模式

MasterHigh Availability Manager and Toolsfor MySQL.是采用PERL语音编写的一个脚本管理工具,该工具适用于MySQL Replication环境,目的是在与维持master主库的高可用性。

MHA是自动的master故障转移和slave提升的软件包,基于标准的MySQL复制(异步、半同步)

MHA Manager管理节点可以单独部署在一个独立服务器上管理多个master-slave集群,也可以部署在一台slave上。MHA Manager探测集群中的node节点

MHA有两个组成部分。

MHA Manager (管理节点)

MHA node (数据节点)

下载地址:

https://github.com/yoshinorim/mha4mysql-manager/releases

https://github.com/yoshinorim/mha4mysql-node/releases

MHA Manager管理节点可以单独部署在一台服务器上管理多个master-slave集群,也可以部署在一台slave上,MHA Manager探测集群中的node节点,当发现master出现故障时,它可以自动将具有最新数据的slave提升为新master,然后将所有其他slave导向新的master上。

整个故障转移过程对应用程序是透明的,MHA node数据节点可以运行在每台Mysql服务器上,

MHA的目的是维持MYSQL Replication 中master库的高可用性,其最大特点是可以修复多个slave之间的差异日志,最终使所有slave保持数据一致,然后从中选择出一个充当新的master,并将其他slave指向它。当master出现故障时,可以通过对比slave之间I/O thread读取主库binlog的position号,选取最接近的slave作为备选主库,其他的从库可以通过与备选主库对比生成差异的中继日志,在备选主库上应用从原来master保存的binlog,同时将备选主库提升为master,最后在其他slave上应用相应的差异中继日志并从新master开始复制。

环境配置

\

主服务器1

从服务器1

从服务器2

OS

Centos el7.x86_64

Centos el7.x86_64

Centos el7.x86_64

IP

192.168.31.79

192.168.31.188

192.168.31.90

HOSTNAME

mysql

Mysql2

Mysql3

Mysql-version

5.7.23

5.7.23

5.7.23

数据库

TEST



备注1

vip 192.168.31.100



备注2


管理节点


备注3


候选节点


备注4

单网卡 名:enp0s3

单网卡 名:enp0s3

单网卡 名:enp0s3

1.安装Mysql

三个节点安装mysql

同时,在主节点创建数据库TEST及TEST数据库下建立若干表,用于测试目的。

2.建立账号

三个节点均运行

建立复制账号

mysql> create user 'rep1'@'192.168.31.%' identified by 'Oracle123';

mysql> grant replication slave on *.* to 'rep1'@'192.168.31.%';

mysql> flush privileges;

建立管理账号

mysql> create user 'dba'@'192.168.31.%' identified by 'Oracle123';

mysql> grant all privileges on *.* to 'dba'@'192.168.31.%';

mysql> flush privileges;

3.编辑配置文件

主服务器1

[root@mysql ~]# vi /etc/my.cnf

添加内容如下

gtid_mode=on

enforce_gtid_consistency=on

log_bin=on

binlog_format=row

server-id=79

log-bin = master-log

relay-log = relay-log

skip_name_resolve

从服务器1

[root@mysql2 ~]# vi /etc/my.cnf

gtid_mode=on

enforce_gtid_consistency=on

log_slave_updates=1

server-id=188

relay-log = relay-log

log-bin = master-log

skip_name_resolve

relay_log_purge = 0

## read_only = ON 该从库会被选为候选主库,故取消read_only

从服务器2

[root@mysql3 ~]# vi /etc/my.cnf

gtid_mode=on

enforce_gtid_consistency=on

log_slave_updates=1

server-id=90

relay-log = relay-log

log-bin = master-log

skip_name_resolve

relay_log_purge = 0

read_only = ON

4.备份还原数据库

主服务器1

备份TEST数据库

[root@mysql ~]# mysqldump --single-transaction -uroot -pOracle123 TEST > TEST_20200316.sql

从服务器1

[root@mysql2 ~]# scp root@192.168.31.79:/root/TEST_20200316.sql .

mysql> create database TEST;

[root@mysql2 ~]# mysql -uroot -pOracle123 TEST < TEST_20200316.sql

从服务器2

[root@mysql3 ~]# scp root@192.168.31.79:/root/TEST_20200316.sql .

mysql> create database TEST;

[root@mysql3 ~]# mysql -uroot -pOracle123 TEST < TEST_20200316.sql

5.重启数据库

三个节点都重启

[root@mysql ~]# service mysql stop

[root@mysql ~]# service mysql start

6.从服务器配置

从服务器两个节点都执行

[root@mysql2 bin]# mysql -uroot -p

mysql> change master to master_host='192.168.31.79',master_user='rep1',master_password='Oracle123',master_port=3306,master_auto_position=1;

mysql> start slave;

mysql> show slave status\G

注:如果以上执行change master有报错,Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'

解决方式如下:

mysql> change master to master_auto_position=0;

mysql> start slave;

注:如果执行以上出现报错,

Last_Error: Error 'Table 'test4' already exists' on query. Default database: 'TEST'. Query: 'create table test4 (id integer,name varchar(200))'

解决方式如下:

主库:mysql> SHOW MASTER STATUS\g --获取File Position

从库执行

mysql> change master to master_host='192.168.31.79',master_user='rep1', master_password='Oracle123',master_port=3306,master_log_file='master-log.000001',master_log_pos=154;

主服务器1

[root@mysql ~]# mysql -uroot -p

mysql> show master status;

7.验证主从同步

主服务器1

mysql> use TEST;

mysql> insert into test2 values (1,'test1');

mysql> commit;

从服务器1

mysql> use TEST;

mysql> select * from test2;

从服务器2

mysql> use TEST;

mysql> select * from test2;

8.安装MHA之配置互信

三个节点均执行(包含管理节点)

[root@mysql ~]# cd .ssh/

[root@mysql .ssh]# ssh-keygen -t dsa -P '' -f id_dsa

[root@mysql .ssh]# cat id_dsa.pub >> authorized_keys

主服务器接收秘钥

主服务器操作

[root@mysql .ssh]# scp 192.168.31.188:/root/.ssh/id_dsa.pub ./id_dsa.pub_188

[root@mysql .ssh]# scp 192.168.31.90:/root/.ssh/id_dsa.pub ./id_dsa.pub_90

[root@mysql .ssh]# cat id_dsa.pub_188 >> authorized_keys

[root@mysql .ssh]# cat id_dsa.pub_90 >> authorized_keys

[root@mysql .ssh]# scp authorized_keys 192.168.31.188:/root/.ssh/

[root@mysql .ssh]# scp authorized_keys 192.168.31.90:/root/.ssh/

三个节点配置host

三个节点均执行

[root@mysql ~]# vi /etc/hosts

添加内如如下:

192.168.31.79 mysql

192.168.31.188 mysql2

192.168.31.90 mysql3

验证

三个节点均互相测试,不需要输入密码即成功

[root@mysql .ssh]# ssh mysql2

[root@mysql .ssh]# ssh mysql3

9.安装MHA相关rpm

NODE节点安装

[root@mysql soft]# yum install -y perl-CPAN

[root@mysql soft]# yum install -y mha4mysql-node-0.58-0.el7.centos.noarch.rpm

管理节点安装(即从服务器1)

如果缺少包,可以下载之后在安装

https://centos.pkgs.org/

[root@mysql2 ~]# yum install perl-Config-Tiny perl-Email-Date-Format perl-File-Remove perl-Log-Dispatch perl-Mail-Sender perl-Mail-Sendmail perl-MIME-Lite perl-MIME-Types perl-Module-Install perl-Module-ScanDeps perl-Parallel-ForkManager perl-YAML -y

[root@mysql2 soft]# yum install mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

10.配置MHA脚本

每一个节点

[root@mysql ~]# cd /usr/local/

[root@mysql local]# mkdir mha

管理节点(从服务器1)

[root@mysql2 soft]# mkdir /usr/local/mha

[root@mysql2 mha]# vi mha.conf

添加内容如下:

[server default]

user = dba

password = Oracle123

ssh_user = root

repl_user = rep1

repl_password = Oracle123

ping_interval = 1

ping_type = SELECT

manager_workdir=/usr/local/mha

manager_log=/usr/local/mha/manager.log

remote_workdir=/usr/local/mha

master_ip_failover_script="/usr/local/mha/master_ip_failover"

master_ip_online_change_script="/usr/local/mha/master_ip_online_change"

shutdown_script=""

report_script=""

#check_repl_delay=0

[server1]

hostname=mysql

port=3306

master_binlog_dir="/u01/data"

candidate_master=1 ##优先选择该节点为候选节点

[server2]

hostname=mysql2

port=3306

master_binlog_dir="/u01/data"

candidate_master=1

[server3]

hostname=mysql3

port=3306

master_binlog_dir="/u01/data"

no_master =1 ##不选择该节点为候选节点

[root@mysql2 mha]# vi master_ip_failover

添加内容如下

#!/usr/bin/env perl

use strict;

use warnings FATAL => 'all';

use Getopt::Long;

my (

$command, $ssh_user, $orig_master_host, $orig_master_ip,

$orig_master_port, $new_master_host, $new_master_ip, $new_master_port

);

my $vip = '192.168.31.100/32'; # Virtual IP,该ip具体参考步骤12添加IP,显示出的结果

my $key = "0";

my $int = "enp0s3";

##my $ssh_start_vip = "/sbin/ifconfig $int:$key $vip"; --本环境为centos7,故注释该指令

##my $ssh_stop_vip = "/sbin/ifconfig $int:$key down"; --本环境为centos7,该指令无效

my $ssh_start_vip = "/sbin/ip addr add $vip dev $int";

my $ssh_stop_vip = "/sbin/ip addr del $vip dev $int";

my $arp_effect = "/sbin/arping -Uq -s192.168.31.100 -I $int 192.168.31.255 -c 3"; # Virtual IP and gatway

#my $test = "echo successfull >/tmp/test.txt";

$ssh_user = "root";

GetOptions(

'command=s' => \$command,

'ssh_user=s' => \$ssh_user,

'orig_master_host=s' => \$orig_master_host,

'orig_master_ip=s' => \$orig_master_ip,

'orig_master_port=i' => \$orig_master_port,

'new_master_host=s' => \$new_master_host,

'new_master_ip=s' => \$new_master_ip,

'new_master_port=i' => \$new_master_port,

);

exit &main();

sub main {

print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";

if ( $command eq "stop" || $command eq "stopssh" ) {

# $orig_master_host, $orig_master_ip, $orig_master_port are passed.

# If you manage master ip address at global catalog database,

# invalidate orig_master_ip here.

my $exit_code = 1;

eval {

print "Disabling the VIP on old master: $orig_master_host \n";

&stop_vip();

$exit_code = 0;

};

if ($@) {

warn "Got Error: $@\n";

exit $exit_code;

}

exit $exit_code;

}

elsif ( $command eq "start" ) {

# all arguments are passed.

# If you manage master ip address at global catalog database,

# activate new_master_ip here.

# You can also grant write access (create user, set read_only=0, etc) here.

my $exit_code = 10;

eval {

print "Enabling the VIP - $vip on the new master - $new_master_host \n";

&start_vip();

$exit_code = 0;

};

if ($@) {

warn $@;

exit $exit_code;

}

exit $exit_code;

}

elsif ( $command eq "status" ) {

print "Checking the Status of the script.. OK \n";

#`ssh $ssh_user\@cluster1 \" $ssh_start_vip \"`;

&status();

exit 0;

}

else {

&usage();

exit 1;

}

}

# A simple system call that enable the VIP on the new master

sub start_vip() {

`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;

`ssh $ssh_user\@$new_master_host \" $arp_effect \"`;

# `ssh $ssh_user\@$new_master_host \" $test \"`;

}

# A simple system call that disable the VIP on the old_master

sub stop_vip() {

`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;

}

sub status() {

print `ssh $ssh_user\@$orig_master_host \" ip add show $int \"`;

}

sub usage {

print

"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_maste

r_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";

}

[root@mysql2 mha]# vi master_ip_online_change

添加内容如下:

#!/usr/bin/env perl

use strict;

use warnings FATAL => 'all';

use Getopt::Long;

use MHA::DBHelper;

use MHA::NodeUtil;

use Time::HiRes qw( sleep gettimeofday tv_interval );

use Data::Dumper;

my $_tstart;

my $_running_interval = 0.1;

my $vip = "192.168.31.100/32";

my $if = "enp0s3";

my (

$command, $orig_master_is_new_slave, $orig_master_host,

$orig_master_ip, $orig_master_port, $orig_master_user,

$orig_master_password, $orig_master_ssh_user, $new_master_host,

$new_master_ip, $new_master_port, $new_master_user,

$new_master_password, $new_master_ssh_user,

);

GetOptions(

'command=s' => \$command,

'orig_master_is_new_slave' => \$orig_master_is_new_slave,

'orig_master_host=s' => \$orig_master_host,

'orig_master_ip=s' => \$orig_master_ip,

'orig_master_port=i' => \$orig_master_port,

'orig_master_user=s' => \$orig_master_user,

'orig_master_password=s' => \$orig_master_password,

'orig_master_ssh_user=s' => \$orig_master_ssh_user,

'new_master_host=s' => \$new_master_host,

'new_master_ip=s' => \$new_master_ip,

'new_master_port=i' => \$new_master_port,

'new_master_user=s' => \$new_master_user,

'new_master_password=s' => \$new_master_password,

'new_master_ssh_user=s' => \$new_master_ssh_user,

);

exit &main();

sub drop_vip {

my $output = `ssh -o ConnectTimeout=15 -o ConnectionAttempts=3 $orig_master_host /sbin/ip addr del $vip/32 dev $if`;

}

sub add_vip {

my $output = `ssh -o ConnectTimeout=15 -o ConnectionAttempts=3 $new_master_host /sbin/ip addr add $vip/32 dev $if`;

}

sub current_time_us {

my ( $sec, $microsec ) = gettimeofday();

my $curdate = localtime($sec);

return $curdate . " " . sprintf( "d", $microsec );

}

sub sleep_until {

my $elapsed = tv_interval($_tstart);

if ( $_running_interval > $elapsed ) {

sleep( $_running_interval - $elapsed );

}

}

sub get_threads_util {

my $dbh = shift;

my $my_connection_id = shift;

my $running_time_threshold = shift;

my $type = shift;

$running_time_threshold = 0 unless ($running_time_threshold);

$type = 0 unless ($type);

my @threads;

my $sth = $dbh->prepare("SHOW PROCESSLIST");

$sth->execute();

while ( my $ref = $sth->fetchrow_hashref() ) {

my $id = $ref->{Id};

my $user = $ref->{User};

my $host = $ref->{Host};

my $command = $ref->{Command};

my $state = $ref->{State};

my $query_time = $ref->{Time};

my $info = $ref->{Info};

$info =~ s/^\s*(.*?)\s*$/$1/ if defined($info);

next if ( $my_connection_id == $id );

next if ( defined($query_time) && $query_time < $running_time_threshold );

next if ( defined($command) && $command eq "Binlog Dump" );

next if ( defined($user) && $user eq "system user" );

next

if ( defined($command)

&& $command eq "Sleep"

&& defined($query_time)

&& $query_time >= 1 );

if ( $type >= 1 ) {

next if ( defined($command) && $command eq "Sleep" );

next if ( defined($command) && $command eq "Connect" );

}

if ( $type >= 2 ) {

next if ( defined($info) && $info =~ m/^select/i );

next if ( defined($info) && $info =~ m/^show/i );

}

push @threads, $ref;

}

return @threads;

}

sub main {

if ( $command eq "stop" ) {

## Gracefully killing connections on the current master

# 1. Set read_only= 1 on the new master

# 2. DROP USER so that no app user can establish new connections

# 3. Set read_only= 1 on the current master

# 4. Kill current queries

# * Any database access failure will result in script die.

my $exit_code = 1;

eval {

## Setting read_only=1 on the new master (to avoid accident)

my $new_master_handler = new MHA::DBHelper();

# args: hostname, port, user, password, raise_error(die_on_error)_ or_not

$new_master_handler->connect( $new_master_ip, $new_master_port,

$new_master_user, $new_master_password, 1 );

print current_time_us() . " Set read_only on the new master.. ";

$new_master_handler->enable_read_only();

if ( $new_master_handler->is_read_only() ) {

print "ok.\n";

}

else {

die "Failed!\n";

}

$new_master_handler->disconnect();

# Connecting to the orig master, die if any database error happens

my $orig_master_handler = new MHA::DBHelper();

$orig_master_handler->connect( $orig_master_ip, $orig_master_port,

$orig_master_user, $orig_master_password, 1 );

## Drop application user so that nobody can connect. Disabling per-session binlog beforehand

$orig_master_handler->disable_log_bin_local();

# print current_time_us() . " Drpping app user on the orig master..\n";

print current_time_us() . " drop vip $vip..\n";

#drop_app_user($orig_master_handler);

&drop_vip();

## Waiting for N * 100 milliseconds so that current connections can exit

my $time_until_read_only = 15;

$_tstart = [gettimeofday];

my @threads = get_threads_util( $orig_master_handler->{dbh},

$orig_master_handler->{connection_id} );

while ( $time_until_read_only > 0 && $#threads >= 0 ) {

if ( $time_until_read_only % 5 == 0 ) {

printf

"%s Waiting all running %d threads are disconnected.. (max %d milliseconds)\n",

current_time_us(), $#threads + 1, $time_until_read_only * 100;

if ( $#threads < 5 ) {

print Data::Dumper->new( [$_] )->Indent(0)->Terse(1)->Dump . "\n"

foreach (@threads);

}

}

sleep_until();

$_tstart = [gettimeofday];

$time_until_read_only--;

@threads = get_threads_util( $orig_master_handler->{dbh},

$orig_master_handler->{connection_id} );

}

## Setting read_only=1 on the current master so that nobody(except SUPER) can write

print current_time_us() . " Set read_only=1 on the orig master.. ";

$orig_master_handler->enable_read_only();

if ( $orig_master_handler->is_read_only() ) {

print "ok.\n";

}

else {

die "Failed!\n";

}

## Waiting for M * 100 milliseconds so that current update queries can complete

my $time_until_kill_threads = 5;

@threads = get_threads_util( $orig_master_handler->{dbh},

$orig_master_handler->{connection_id} );

while ( $time_until_kill_threads > 0 && $#threads >= 0 ) {

if ( $time_until_kill_threads % 5 == 0 ) {

printf

"%s Waiting all running %d queries are disconnected.. (max %d milliseconds)\n",

current_time_us(), $#threads + 1, $time_until_kill_threads * 100;

if ( $#threads < 5 ) {

print Data::Dumper->new( [$_] )->Indent(0)->Terse(1)->Dump . "\n"

foreach (@threads);

}

}

sleep_until();

$_tstart = [gettimeofday];

$time_until_kill_threads--;

@threads = get_threads_util( $orig_master_handler->{dbh},

$orig_master_handler->{connection_id} );

}

## Terminating all threads

print current_time_us() . " Killing all application threads..\n";

$orig_master_handler->kill_threads(@threads) if ( $#threads >= 0 );

print current_time_us() . " done.\n";

$orig_master_handler->enable_log_bin_local();

$orig_master_handler->disconnect();

## After finishing the script, MHA executes FLUSH TABLES WITH READ LOCK

$exit_code = 0;

};

if ($@) {

warn "Got Error: $@\n";

exit $exit_code;

}

exit $exit_code;

}

elsif ( $command eq "start" ) {

## Activating master ip on the new master

# 1. Create app user with write privileges

# 2. Moving backup script if needed

# 3. Register new master's ip to the catalog database

# We don't return error even though activating updatable accounts/ip failed so that we don't interrupt slaves' recovery.

# If exit code is 0 or 10, MHA does not abort

my $exit_code = 10;

eval {

my $new_master_handler = new MHA::DBHelper();

# args: hostname, port, user, password, raise_error_or_not

$new_master_handler->connect( $new_master_ip, $new_master_port,

$new_master_user, $new_master_password, 1 );

## Set read_only=0 on the new master

$new_master_handler->disable_log_bin_local();

print current_time_us() . " Set read_only=0 on the new master.\n";

$new_master_handler->disable_read_only();

## Creating an app user on the new master

#print current_time_us() . " Creating app user on the new master..\n";

print current_time_us() . "Add vip $vip on $if..\n";

# create_app_user($new_master_handler);

&add_vip();

$new_master_handler->enable_log_bin_local();

$new_master_handler->disconnect();

## Update master ip on the catalog database, etc

$exit_code = 0;

};

if ($@) {

warn "Got Error: $@\n";

exit $exit_code;

}

exit $exit_code;

}

elsif ( $command eq "status" ) {

# do nothing

exit 0;

}

else {

&usage();

exit 1;

}

}

sub usage {

print

"Usage: master_ip_online_change --command=start|stop|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";

die;

}

11.检查状态

管理节点

[root@mysql2 mha]# which masterha_check_ssh

[root@mysql2 mha]# chmod +x master_ip_online_change

[root@mysql2 mha]# chmod +x master_ip_failover

[root@mysql2 mha]# masterha_check_ssh --conf=/usr/local/mha/mha.conf

[root@mysql2 mha]# masterha_check_repl --conf=/usr/local/mha/mha.conf

12.在主库上添加VIP

主服务器1

[root@mysql ~]# ip addr add 192.168.31.100 dev enp0s3

[root@mysql ~]# ip addr show

注意是 100/32

13.启动MHA

管理节点(即从服务器1)

[root@mysql2 mha]# nohup masterha_manager --conf=/usr/local/mha/mha.conf > /tmp/mha_manager.log < /dev/null 2>&1 &

14.检验MHA状态

管理节点(即从服务器1)

[root@mysql2 mha]# masterha_check_status --conf=/usr/local/mha/mha.conf

15.测试验证

主服务器1

[root@mysql ~]# service mysql stop

注:

每次出发MHA切换,需要在管理节点删除mha.failover.complete文件,不然下次切换会报错。

从服务器1(候选节点)

检查

[root@mysql2 mha]# tail -100f manager.log

[root@mysql2 mha]# ip addr show

mysql> show slave status\G

mysql> show master status\G

从服务器2

16.后续操作

将原主库恢复,成为现集群环境的备库

现主库操作

mysql> show master status;

原主库操作

[root@mysql data]# service mysql start

[root@mysql data]# mysql -uroot -p

mysql> change master to master_host='192.168.31.188',master_user='rep1', master_password='Oracle123',master_port=3306,master_log_file='master-log.000001',master_log_pos=409;

mysql> start slave;

mysql> show slave status\G

关于MYSQL架构中如何主从MHA就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

节点 服务器 服务 管理 数据 三个 内容 数据库 配置 环境 集群 备注 故障 备选 主从 多个 差异 日志 目的 网卡 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 苏州找大状互联网科技有限公司 科技和互联网公司 科技与互联网 深圳市运趣互联网科技有限公司 济南华为互联网科技产业总部基地 小米互联网科技园设置 汽车互联网创新科技园 中化能源互联网科技招聘 互联网科技公司有风险吗 长沙互联网科技 吉林省码上互联网科技电话 世界互联网科技成果奖 艺电能源互联网科技有限公司招聘 长沙渺峰互联网科技有限公司 科技信息时代互联网发展 科技互联网专业工作会议发言稿 互联网科技创新创业项目 互联网科技创业计划的风险分析 现代科技的标志之一的互联网 互联网 科技节活动 微视频大赛 南京欣网互联网络科技有限公司 安徽鑫晟辉互联网科技 奇酷互联网络科技公司 时间互联网络科技 老年人脱离互联网科技的作文 浙江互联网科技研学营 未来五年的互联网科技 广州互联网高科技取餐柜 好易买互联网科技 互联网金融金融科技
0