本文记录自内部分享,需要一定的 MySQL 基础。欢迎大家在评论区讨论、交流~
MySQL Group Replication(简称 MGR), MySQL 组复制。
MGR 是 MySQL 官方推出的一种基于 paxos 协议的状态机复制,实现了分布式下数据的最终一致性。MySQL 组复制提供了高可用、高扩展、高可靠的 MySQL 集群解决方案。
MGR 支持两种模式:单主、多主。其中单主模式是官方推荐的,也是在来也科技内部广泛应用的,我们接下来的内容都是以单主模式为背景的。
可能有同学会质疑,公有云上的高可用架构大多是主从啊,为什么来也科技要选择 MGR ?
那首先,我们就要知道 “主从” 和 MGR 的优缺点分别是什么?
来也科技作为一家重心放在 ToB 的企业,我们着重考虑私有部署时,如何保证客户环境的可用性。客户的环境,我们看不到,更无法控制,在这样的情况下,我们会尽量求稳。
维护主从高可用架构的应用,通常面向大规模集群运维,往往会引入复杂的交互和新的中间件。对于我们这种只需要部署一套集群的 ToB 需求,显然是不合适的。
综合考虑之下,我们选择 MGR 作为私有部署时的高可用架构。
· 最少 3 个节点,最多 9 个节点
· 节点越多,容错性越强,但交互越多,可能会影响效率
· 存储引擎只能使用 InnoDB
· 表中必须带有主键
· 一次只能加入一个节点。如果一次性添加多个节点,可能能执行成功,也可能会报错
· 只支持 IPv4 网络
· 必须使用 row-base 格式的binlog
· MGR 模式下不支持过滤指定信息的 *** 作
来也科技在给客户做私有部署时,如果客户提供 MySQL 高可用环境,那么会直接使用客户的环境。
否则,部署团队将为客户搭建三节点的 MGR 高可用架构。整体架构图:
如图所示,在应用和 MGR 集群的中间层选用多节点 proxysql 做路由,配置读写分离和故障检测机制,确保读写流量分发正确。proxysql 只要有一个节点存活,即可正常提供服务。(除非扛不住压力!)
在这种架构下,我们可以实现:
· 如果主库发生故障 -- 自动切换
· 如果从库发生故障 -- 将其下线
对于底层的 MGR 集群,宕机一个 mysql 实例时,不影响业务正常使用;宕机两个 mysql 实例时,集群只可读,不可写(因为此时已经无法满足 paxos 的多数投票要求)
首先,我们以一个“一波三折”的场景为例,切实感受下 MGR 是如何运作的。
假设存在一个三节点的 MGR 集群,三个节点分别部署在三台实例上。
此时,应用发起一个事务执行请求。 单主模式下,只有primary node 可以接收请求:
1. primary 接受到请求后,想组所有成员同步请求,进行事务认证。事务认证包含 3 个部分:
1-1. 冲突检测
1-2. gtid分配器
1-3. 事务组提交信息分配器
2. 如果检测失败
2-1. primary:回滚
2-2. secondary:丢弃 binlog event (冲突检测时带来的)
3. 如果检测成功:
3-1. primary :记 binlog, 分配 GTID
3-2. secondary:将 binlog event (冲突检测时带来的)信息写入 relay log
4. secondary 应用 relay log ,执行 sql ,并记录日志(通常情况下,我们建议将集群内所有 node 都配置在 seed 中,即:每个节点都可能成为 donor ,所以都要记 binlog)
以上,就是事务在 MGR 中完整的执行流程。
假设,运行一段时间后,其中某个 secondary 节点因服务器宕机原因脱离集群,且长时间未被发现。直至节前巡检时,才被报出来。
补充说明:来也监控项目已经提上日程了,部署后,便不会存在这个风险了。
此时,售后同学重启服务器,启动 mysql 实例(假设顺利启动),执行 start group_replication *** 作。
这个命令会执行什么 *** 作呢?
本地恢复:应用自己本地 relay log 中的日志
全局恢复:从集群中活跃的节点中任选一个作为 donor,用 recovery 线程 dump 它的binlog,来恢复自己的数据
恢复线程 requestdump 建立与 donor 的复制关系,该函数携带了待恢复节点的 gtid_executed 信息。
donor 端逆序遍历 binlog 文件,通过判断 binlog 文件的 Previous-GTIDs 来找到第一个不属于 gtid_executed 的事务,从该事务开始进行数据复制。
命令执行过后,观察 replication_group_members 表的数据,如果目标节点的状态是 ONLINE,则视为集群恢复成功。
但我们假设此 *** 作并未成功,日志中有报错:the master has purged binary logs containing GTIDs that the slave requires
这个错误的意思是:节点脱离集群时间过长,已无法通过现存节点的 binlog 直接恢复了。
重做数据。当然是重做数据!
我们需要清除这个下线节点的信息,创建一个新的实例,选择任一正常节点进行数据全量备份,并将其应用至新实例上。
全量数据恢复完成后,执行 start group_replication 命令,开启 MGR 同步,追平数据后,MGR 会将节点状态置为 ONLINE,然后开始正常接收流量请求。
在传统的主从复制中,DBA 需要在 change master 时手动设置增量同步开始的 GTID(更早版本需要指定 binlog file 和 position)。
但是部署过 MGR 的同学会发现,MGR 同步时只需要指定用户名密码即可。那它是怎么找点的呢?
不同的备份方式,对应着不同的找点方式,接下来我们以 mysqldump 为例,详细的讲解下这个过程。
mysqldump 全量数据,使用 gtid_purged 记录备份时已经执行过的事务:
mysqldump --set-gtid-purged=ON --single-transaction --all-databases -uroot -p -h 127.0.0.1 >mgr.sql
查看生成的 sql 文件,可以看到开始处有相关标识:
在新节点上使用如下命令清空 GTID 信息:
STOP GROUP_REPLICATION
reset master
接下来,应用文件 source mgr.sql,红框圈起来的语句会被一起执行。
完成后,开启 MGR 同步,就会自动跳过这些标识为 purged 的事务了。
当有成员加入或退出时,组会自动调整自身结构:
· 成员的加入和退出需走 paxos 协议,由多数成员同意后方可执行成功
· 如果多数节点已经处于离线状态了,那么不可执行主动离组 *** 作(投票会无法通过)。
离组分为主动离组和被动离组:
· 主动离组:
只有执行 stop replication 命令才算主动离组
相当于总数变为 n-1
无论主动离组多少成员,都不会影响投票
· 被动离组:
因故障等原因导致意外下线
总数不变
影响投票
当有多数节点被动离组后,集群不可用
1. group_replication_applier:该通道用于回放本地 relay log 中的日志。
2. group_replication_recovery:当有节点加入 Group 时,需要用到另一个复制通道 group_replication_recovery,它是一个传统的 Master-Slave 异步复制通道。
MGR 常见的调优方式有三种,分别是:
并行复制
压缩
调整 GCT
如果设置了并行复制 slave_parallel_workers,那么这些参数也要被设置,用于确保所有的组成员按照相同的顺序执行并提交事务:
slave_preserve_commit_order=1
slave_parallel_type=LOGICAL_CLOCK
压缩语句:
STOP GROUP_REPLICATION
SET GLOBALgroup_replication_compression_threshold = 2097152
START GROUP_REPLICATION
超出这个指定范围,就不压缩了。
官方文档中提示:当网络带宽成为瓶颈时,通过压缩消息,可以提高集群整体 30% - 40% 的性能。
mysql>SET GLOBAL group_replication_poll_spin_loops= 10000
GCT接收来自组和 MGR 插件的消息,处理与仲裁和故障检测相关的任务,发送一些保活的通讯消息,还处理 MySQLServer 与组之间传入和传出的事务。GCT 会等待队列中的传入消息。当队列中没有消息时,GCT将会进行等待。
在某些情况下,通过将这个等待配置得稍微长一些(进行主动等待),可以减少 *** 作系统执行上下文切换时从处理器中换出GCT线程的次数。
常见的安全手段有两种:
1. 控制节点白名单。设置 group_replication_ip_whitelist 参数,不再此范围的节点,不允许加入
2. 配置 SSL:
new_member> SET GLOBAL group_replication_recovery_use_ssl=1
new_member> SET GLOBAL group_replication_recovery_ssl_ca= '.../cacert.pem'
new_member> SET GLOBAL group_replication_recovery_ssl_cert= '.../client-cert.pem'
new_member> SET GLOBAL group_replication_recovery_ssl_key= '.../client-key.pem'
MySQL 5.7.22 之前,可能会出现数据不一致的风险。这种情况发生在成员短暂离组,在组感知前,自己又重新加入组内的时候,官方文档描述如下:
In this situation, the rejoining member forgets its previousstate, but if other members send it messages that are intended for itspre-crash state, this can cause issues including possible data inconsistency.
To counter this possibility, from MySQL 5.7.22, servers aregiven a unique identifier when they join a group . This enables GroupReplication to be aware of the situation where a new incarnation of the sameserver (with the same address but a new identifier) is trying to join the groupwhile its old incarnation is still listed as a member. The new incarnation isblocked from joining the group until the old incarnation can be removed by areconfiguration. If Group Replication is stopped and restarted on the server,the member becomes a new incarnation and cannot rejoin until the suspiciontimes out.
精准的定位问题是解决问题和优化系统的前提!当集群故障时,我们首先要判断集群当前处于什么状态,优先恢复使用,尽可能地保留现场进行故障排查和恢复。
所有节点上执行查看集群成员信息命令:
Q: 为什么要在所有节点上执行?
A: 因为可能会发生网络分区,出现若干节点互联,分成若干集群的情况。集群一旦分裂,互相感知不到对方存在。
以三个节点为例,常见分裂拓扑图:
如果大多数节点存活(n=2f + 1 ) 且在同一个 group 中提供服务,我们认为,这仍是一个可用集群。
即:同一个 group 中 node 数大于 f ,且状态都是 ONLINE 的情况下,认定集群可用。
此时,优先使用可用集群提供服务,并进行后续问题排查。
主节点提供读写服务,从节点提供只读服务。
无论是应用直连,还是通过代理层(proxy 等)进行连接,当务之急都是确认主节点是谁。
命令:select MEMBER_HOST, MEMBER_PORT,MEMBER_STATE from performance_schema.replication_group_members m inner join performance_schema.global_status g on m.MEMBER_ID=g.VARIABLE_VALUE and VARIABLE_NAME = 'group_replication_primary_member'
知晓谁是主节点,谁是从节点后,应用或者代理,就可以进行相应的配置。
错误日志!错误日志!错误日志!
有故障,第一时间查看错误日志。错误日志存放位置:
打开日志文件,查看错误信息。
注意: 错误信息,不仅要在出故障的实例上查看。因为 MGR 是”大多数原则“,所以每一个实例上的错误信息,都可能不是完全的。
比如实例意外 down 掉,此时故障实例本身就可能来不及记录错误日志。
除了实例级别的错误日志外,MGR 视图还可能自己记录最后的错误信息,通常日志中会有相关提示。比如,日志中存在:
[ERROR] Plugin group_replication reported: 'For details please check performance_schema.replication_connection_status table and error log messages of Slave I/O for channel group_replication_recovery.'
常见错误:[GCS]Connection attempt from IP address 192.168.9.208 refused
出现场景:MGR 白名单设置不正确
解决办法:查看该实例所在的网段,是否在 MGR 的白名单中
命令:show global variables like 'group_replication_ip_whitelist'
通常我们建议直接设置成全网段访问,由其他层(region、安全组等)控制连通性。
不排除私有部署的客户对于安全性要求极高,要求设置指定网段访问,那么此时,就要查看一下实例是否存在于这个白名单中。
注意:MGR 中的节点,每个白名单配置都可能不一样(强烈不建议!建议配置成一致的!),所以,要把集群中所有的节点都查一遍,避免出现后续问题。
常见错误:This member has more executed transactions than those present in the group.
出现场景:
1. 有应用直连,往里写数据
2. 有人误在从库上直接 *** 作
3. 错误的恢复手段:这个最为常见
解决办法:
1. 查看哪些数据被错误应用,进行相应处理
2. 找到最后同步的 GTID 位点
3. reset master
4. 设置最后 gtid_purged 为要继续同步的 GTID 位点
常见错误:Member was expelled from the group due to network failures, changing member status to ERROR
出现场景:网络延迟
解决方法:等待网络恢复正常后,重新加入集群即可
常见错误:the master has purged binary logs containing GTIDs that the slave requires
出现场景:从库脱离群组时间太长,无法通过已有的 binlog 进行恢复了
解决方法:重做数据(mysqldump 或 xtrabackup)后,加入群组
select TABLE_SCHEMA, TABLE_NAME from information_schema.tables where TABLE_SCHEMA not in ('information_schema','mysql', 'performance_schema', 'test', 'sys') and TABLE_NAME not in (select table_name from information_schema.TABLE_CONSTRAINTS where TABLE_SCHEMA not in ('information_schema','mysql', 'performance_schema', 'test', 'sys') and CONSTRAINT_TYPE = 'PRIMARY KEY')
select TABLE_SCHEMA, TABLE_NAME from information_schema.tables where TABLE_SCHEMA not in ('information_schema','mysql', 'performance_schema', 'test', 'sys') and engine <>'InnoDB'
本文作者、编辑:刘桐烔
欢迎大家点赞、在看、关注~
Zipkin的拓扑服务zipkin-dependencies是作为zipkin的一个独立的离线服务,也就是说,只启动zipkin服务,是没法看到拓扑的,还需要自己离线启动zipkin-dependencues服务。
其中ES配置参数如下:
Zipkin出了支持elasticsearch存储,还有mysql,cassard,详细配置信息请看 源码Readme
1、图中线条说明
服务之间的线条,遵循以下原则:
2、主调被调次数说明
点开每一个服务,可以看到主调被调,比如我在拓扑图中点击
某个服务,可以与此服务有直接调用关系的服务有哪些,效果如下:
其中Uses by表示此服务作为被调服务,被哪些服务调用了;Uses表示此服务调用了哪些其他服务。
在上面的图中点击某个主调或被调服务,即可看到具体的调用次数,以及失败次数,效果如下:
通过拓扑图,宏观上,我们可以快速了解服务之间的调用关系,同时也可以知道哪些服务间调用有问题,且可以知道出现问题的一个量级是多少(失败数,调用总数)。
Zipkin拓扑denpendencies是基于上报的链路span数据再次构建出的描述链路拓扑的一种新的数据结构。
构建链路的第一步就是读取Span数据。Zipkin外部数据源支持三种,分别是Mysql,Cassandra,Elasticsearch,因此构建拓扑时,将从这三种数据源中读取Span数据。
读取Span数据源后,需要对其处理,计算出链路的拓扑。因为Span的数据量很大,普通程序计算处理无法完成任务,因此需要用到大数据框架。Zipkin官方选用的是Spark框架。Spark对Span数据进行处理,最后生成拓扑数据DenpendencyLink,然后持久化到存储中。
前端请求拓扑(DependencyLink)时,即按照查询条件,查询已经持久化后的DependencyLink,然后经过UI渲染,进行页面展示。
启动Zipkin-dependencies服务时,会传入几个参数,分别是时间day和存储类型storageType。Zipkin-dependencies服务是以天为单位进行建立拓扑,因此day将决定建立那一天的拓扑;而storageType将决定从什么储存中读取数据。
1、获取日期:
2、获取存储类型:
3、根据不同的存储启动不同的jOb:
不同的存储会定义不同Job类,因此有CassandraDependenciesJob,MySQLDependenciesJob,MySQLDependenciesJob,ElasticsearchDependenciesJob。 不同的Job主要区别在于读取Span的方式不同,而Spark对Span进行处理计算的方式基本都是相同的。 本文主要分析ElasticsearchJOb。
Job中主要逻辑都在run方法中,ElastichserchJob的Run方法定义如下:
主要步骤如下:
1、首先通过Spark的配置属性Conf,创建一个JavaSparkContext对象sc:
2、然后读取elasticsearch span数据源:
3、读取数据源后,就可以对Span进行处理了,首先按照TraceId 进行Group分组:
其中JSON_TRACE_ID Function定义如下:
4、Span按照TraceId Group 分组后,接着对Span进行处理, 创建出DenpendencyLink。
5、上面方法最终返回的是个Map类型,将其转化为pari类型,再对其进行一个reduceByKey *** 作:
6、Spark对Span的计算 *** 作到这儿基本就完成了,最后将DependencyLink转化为Jso形式:
7、对于计算好的拓扑Links,将其持久化到Elasticsearch中:
整个过程到此完毕,其中最复杂也是最核心的逻辑就是计算出链路拓扑Denpendencylink,此步骤在Function TraceIdAndJsonToDependencyLinks(logInitializer, decoder)中。接下来详细分析TraceIdAndJsonToDependencyLinks完成的工作。
首先介绍一下DenpendencyLink数据结构。DenpendencyLink就是最终与页面交互的拓扑结构数据单元,字端有:
DenpendencyLink类定义如下:
TraceIdAndJsonToDependencyLinks类的定义如下:
其中call方法中,首先完成对同一TraceId的Span解码:
然后,通过DependencyLinker类构造出DependendyLink,首先构造一个SpanNode Tree:
然后利用深度优先遍历方法遍历整个,统计出CallCounts和errorCounts:
其中callCounts和errorCounts定义如下:
最后,再通过callCounts和errorCounts生成List<DependencyLink>:
这样,最终构建出了DependencyLink。
本文为我的调用链系列文章之一,已有文章如下:
祝大家工作顺利,天天开心!
1.简介
分布式文件系统(Distributed File System)是指文件系统管理的物理存储资源不一定直接连接在本地节点上,而是通过计算机网络与节点相连。分布式文件系统的设计基于客户机/服务器模式。一个典型的网络可能包括多个供多用户访问的服务器。另外,对等特性允许一些系统扮演客户机和服务器的双重角色。例如,用户可以“发表”一个允许其他客户机访问的目录,一旦被访问,这个目录对客户机来说就像使用本地驱动器一样。
当下我们处在一个互联网飞速发展的信息 社会 ,在海量并发连接的驱动下每天所产生的数据量必然以几何方式增长,随着信息连接方式日益多样化,数据存储的结构也随着发生了变化。在这样的压力下使得人们不得不重新审视大量数据的存储所带来的挑战,例如:数据采集、数据存储、数据搜索、数据共享、数据传输、数据分析、数据可视化等一系列问题。
传统存储在面对海量数据存储表现出的力不从心已经是不争的事实,例如:纵向扩展受阵列空间限制、横向扩展受交换设备限制、节点受文件系统限制。
然而分布式存储的出现在一定程度上有效的缓解了这一问题,之所以称之为缓解是因为分布式存储在面对海量数据存储时也并非十全十美毫无压力,依然存在的难点与挑战例如:节点间通信、数据存储、数据空间平衡、容错、文件系统支持等一系列问题仍处在不断摸索和完善中。
2.分布式文件系统的一些解决方案
Google Filesystem适合存储海量大个文件,元数据存储与内存中
HDFS(Hadoop Filesystem)GFS的山寨版,适合存储大量大个文件
TFS(Taobao Filesystem)淘宝的文件系统,在名称节点上将元数据存储与关系数据库中,文件数量不在受限于名称节点的内容空间,可以存储海量小文件LustreOracle开发的企业级分布式系统,较重量级MooseFS基于FUSE的格式,可以进行挂载使用MogileFS
擅长存储海量的小数据,元数据存储与关系型数据库中
1.简介
MogileFS是一个开源的分布式文件系统,用于组建分布式文件集群,由LiveJournal旗下DangaInteractive公司开发,Danga团队开发了包括 Memcached、MogileFS、Perlbal等不错的开源项目:(注:Perlbal是一个强大的Perl写的反向代理服务器)。MogileFS是一个开源的分布式文件系统。
目前使用 MogileFS 的公司非常多,比如国外的一些公司,日本前几名的公司基本都在使用这个.
国内所知道的使用 MogileFS 的公司有图片托管网站 yupoo又拍,digg, 土豆, 豆瓣,1 号店, 大众点评,搜狗,安居客等等网站.基本很多网站容量,图片都超过 30T 以上。
2.MogileFS特性
1) 应用层提供服务,不需要使用核心组件
2)无单点失败,主要有三个组件组成,分为tracker(跟踪节点)、mogstore(存储节点)、database(数据库节点)
3)自动复制文件,复制文件的最小单位不是文件,而是class
4)传输中立,无特殊协议,可以通过NFS或HTTP实现通信
5)简单的命名空间:没有目录,直接存在与存储空间上,通过域来实现
6)不用共享任何数据
3.MogileFS的组成
1)Tracker--跟踪器,调度器
MogileFS的核心,是一个调度器,mogilefsd进程就是trackers进程程序,trackers的主要职责有:删除数据、复制数据、监控、查询等等.这个是基于事件的( event-based ) 父进程/消息总线来管理所有来之于客户端应用的交互(requesting operations to be performed), 包括将请求负载平衡到多个"query workers"中,然后让 mogilefs的子进程去处理.
mogadm,mogtool的所有 *** 作都要跟trackers打交道,Client的一些 *** 作也需要定义好trackers,因此最好同时运行多个trackers来做负载均衡.trackers也可以只运行在一台机器上,使用负载均衡时可以使用搞一些简单的负载均衡解决方案,如haproxy,lvs,nginx等,
tarcker的配置文件为/etc/mogilefs/mogilefsd.conf,监听在TCP的7001端口
2)Database--数据库部分
主要用来存储mogilefs的元数据,所有的元数据都存储在数据库中,因此,这个数据相当重要,如果数据库挂掉,所有的数据都不能用于访问,因此,建议应该对数据库做高可用
3)mogstored--存储节点
数据存储的位置,通常是一个HTTP(webDAV)服务器,用来做数据的创建、删除、获取,任何 WebDAV 服务器都可以, 不过推荐使用 mogstored . mogilefsd可以配置到两个机器上使用不同端口… mogstored 来进行所有的 DAV *** 作和流量,IO监测, 并且你自己选择的HTTP服务器(默认为 perlbal)用来做 GET *** 作给客户端提供文件.
典型的应用是一个挂载点有一个大容量的SATA磁盘. 只要配置完配置文件后mogstored程序的启动将会使本机成为一个存储节点.当然还需要mogadm这个工具增加这台机器到Cluster中.
配置文件为/etc/mogilefs/mogstored.conf,监听在TCP的7500端口
4.基本工作流程
应用程序请求打开一个文件 (通过RPC 通知到 tracker, 找到一个可用的机器). 做一个 “create_open” 请求.
tracker 做一些负载均衡(load balancing)处理,决定应该去哪儿,然后给应用程序一些可能用的位置。
应用程序写到其中的一个位置去 (如果写失败,他会重新尝试并写到另外一个位置去).
应用程序 (client) 通过”create_close” 告诉tracker文件写到哪里去了.
tracker 将该名称和域命的名空间关联 (通过数据库来做的)
tracker, 在后台, 开始复制文件,知道他满足该文件类别设定的复制规则
然后,应用程序通过 “get_paths” 请求 domain+key (key == “filename”) 文件, tracker基于每一位置的I/O繁忙情况回复(在内部经过 database/memcache/etc 等的一些抉择处理), 该文件可用的完整 URLs地址列表.
应用程序然后按顺序尝试这些URL地址. (tracker’持续监测主机和设备的状态,因此不会返回死连接,默认情况下他对返回列表中的第一个元素做双重检查,除非你不要他这么做..)
1.拓扑图
说明:1.用户通过URL访问前端的nginx
2.nginx根据特定的挑选算法,挑选出后端一台tracker来响应nginx请求
3.tracker通过查找database数据库,获取到要访问的URL的值,并返回给nginx
4.nginx通过返回的值及某种挑选算法挑选一台mogstored发起请求
5.mogstored将结果返回给nginx
6.nginx构建响应报文返回给客户端
2.ip规划
角色运行软件ip地址反向代理nginx192.168.1.201存储节点与调度节点1
mogilefs192.168.1.202存储节点与调度节点2
mogilefs192.168.1.203数据库节点
MariaDB192.168.1.204
3.数据库的安装 *** 作并为授权
关于数据库的编译安装,请参照本人相关博文http://wangfeng7399.blog.51cto.com/3518031/1393146,本处将不再累赘,本处使用的为yum源的安装方式安装mysql
4.安装mogilefs. 安装mogilefs,可以使用yum安装,也可以使用编译安装,本处通过yum安装
5.初始化数据库
可以看到在数据库中创建了一些表
6.修改配置文件,启动服务
7.配置mogilefs
添加存储主机
添加存储设备
添加域
添加class
8.配置192.168.1.203的mogilefs 。切记不要初始化数据库,配置应该与192.168.1.202一样
9.尝试上传数据,获取数据,客户端读取数据
上传数据,在任何一个节点上传都可以
获取数据
客户端查看数据
我们可以通过任何一个节点查看到数据
要想nginx能够实现对后端trucker的反向代理,必须结合第三方模块来实现
1.编译安装nginx
2.准备启动脚本
3.nginx与mofilefs互联
查看效果
5.配置后端truckers的集群
查看效果
大功告成了,后续思路,前段的nginx和数据库都存在单点故障,可以实现高可用集群
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)