文档章节

一步步实现redis+sentinel双机热备

AlanVision
 AlanVision
发布于 2016/10/09 15:45
字数 3781
阅读 2178
收藏 117

前言

前些天一直在忙线上环境部署的事情,初步想的是,nginx(keepalive双机热备)+3(tomcat)+2redis(双机热备),但是后来由于阿里云服务器经典网络不提供虚拟IP,无法使用keepalive,nginx双机热备只能暂时先放弃,退而求其次,采用nginx+3tomcat+2redis(双机热备)。nginx+tomcat由于之前配置过,所以重点就落在redis双机热备上,毕竟是线上系统,适当的抗灾能力还是需要的,咱可不能像测试系统那么去玩,否则黑锅就有的背了,毕竟码代码赚点生活费也不容易。

在网上也查了一些资料,redis集群实现大概有以下几种方式:

1.redis-cluster,官方提供的集群搭建方案(过于重量级,比较适合后期数据量较大的时候的使用)

2.redis+keepalive(由于我们使用的阿里云服务器不支持虚拟IP,所以这套方案也就夭折了)

3.redis+zookeeper(需要引入zookeeper,对现有代码变动较大)

4.redis+sentinel(redis自带监控中间件)(代码变动小,配置少,而且能满足双机热备的需求)

基于我们目前的情况以及需求,经过初略对比,我们团队决定选用第四种方案redis+sentinel实现双机热备。

准备工作

1.安装redis-001(主)

$ wget http://download.redis.io/releases/redis-3.2.3.tar.gz
$ tar xzf redis-3.2.3.tar.gz
$ mv redis-3.2.3 redis-001
$ cd redis-001
$ make

2.安装redis-002(从)

$ wget http://download.redis.io/releases/redis-3.2.3.tar.gz
$ tar xzf redis-3.2.3.tar.gz
$ mv redis-3.2.3 redis-002
$ cd redis-002
$ make

3.修改redis-002端口为6380

$ cd /usr/tools/redis-002/
$ vim redis.conf
...找到port 6379改为6380...

4.修改redis默认配置

a.关闭ip绑定,注释redis.conf中bind 127.0.0.1

b.关闭保护模式,将protected-mode yes改为protected-mode no

5.启动redis-001,redis-002

$ cd tools/redis-001/
$ ./src/redis-server redis.conf

出现以下信息就表示启动成功了:

12513:M 09 Oct 11:15:49.061 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
12513:M 09 Oct 11:15:49.061 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
12513:M 09 Oct 11:15:49.061 * DB loaded from disk: 0.000 seconds
12513:M 09 Oct 11:15:49.061 * The server is now ready to accept connections on port 6379

redis主从复制

1.redis 复制的特点

    1). 同一个Master可以同步多个Slaves。
    2). Slave同样可以接受其它Slaves的连接和同步请求,这样可以有效的分载Master的同步压力。因此我们可以将Redis的Replication架构视为图结构。
    3). Master Server是以非阻塞的方式为Slaves提供服务。所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求。
    4). Slave Server同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据。
    5). 为了分载Master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务仍然必须由Master来完成。即便如此,系统的伸缩性还是得到了很大的提高。
    6). Master可以将数据保存操作交给Slaves完成,从而避免了在Master中要有独立的进程来完成此操作。

2.redis复制原理

    在Slave启动并连接到Master之后,它将主动发送一个SYNC命令。此后Master将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,Master将传送整个数据库文件到Slave,以完成一次完全同步。而Slave服务器在接收到数据库文件数据之后将其存盘并加载到内存中。此后,Master继续将所有已经收集到的修改命令,和新的修改命令依次传送给Slaves,Slave将在本次执行这些数据修改命令,从而达到最终的数据同步。
    如果Master和Slave之间的链接出现断连现象,Slave可以自动重连Master,但是在连接成功之后,一次完全同步将被自动执行。

3.redis主从配置

前面也说了,redis主从配置很简单,只需要一个slaveof就可以搞定。

连接redis-002,执行slaveof 192.168.231.130 6379:

C:\Users\lenovo\Desktop\redis>D:
D:\>cd D:\Program Files\Redis-x64-3.0.5
D:\Program Files\Redis-x64-3.0.5>redis-cli.exe -h 192.168.231.130 -p 6380
192.168.231.130:6380> slaveof 192.168.231.130 6379
OK
192.168.231.130:6380>

执行完成后,可以看到服务器上redis-001控制台输出以下内容:

12513:M 09 Oct 11:15:49.061 * DB loaded from disk: 0.000 seconds
12513:M 09 Oct 11:15:49.061 * The server is now ready to accept connections on port 6379
12513:M 09 Oct 11:41:59.371 * Slave 192.168.231.130:6380 asks for synchronization
12513:M 09 Oct 11:41:59.371 * Full resync requested by slave 192.168.231.130:6380
12513:M 09 Oct 11:41:59.371 * Starting BGSAVE for SYNC with target: disk
12513:M 09 Oct 11:41:59.372 * Background saving started by pid 13673
13673:C 09 Oct 11:41:59.388 * DB saved on disk
13673:C 09 Oct 11:41:59.388 * RDB: 6 MB of memory used by copy-on-write
12513:M 09 Oct 11:41:59.462 * Background saving terminated with success
12513:M 09 Oct 11:41:59.462 * Synchronization with slave 192.168.231.130:6380 succeeded

redis-002控制台输出:

13581:S 09 Oct 11:41:59.361 * Connecting to MASTER 192.168.231.130:6379
13581:S 09 Oct 11:41:59.370 * MASTER <-> SLAVE sync started
13581:S 09 Oct 11:41:59.370 * Non blocking connect for SYNC fired the event.
13581:S 09 Oct 11:41:59.371 * Master replied to PING, replication can continue...
13581:S 09 Oct 11:41:59.371 * Partial resynchronization not possible (no cached master)
13581:S 09 Oct 11:41:59.374 * Full resync from master: e2f4e2608956ea6392482c2e0a9429efdebd2b53:1
13581:S 09 Oct 11:41:59.462 * MASTER <-> SLAVE sync: receiving 76 bytes from master
13581:S 09 Oct 11:41:59.463 * MASTER <-> SLAVE sync: Flushing old data
13581:S 09 Oct 11:41:59.463 * MASTER <-> SLAVE sync: Loading DB in memory
13581:S 09 Oct 11:41:59.463 * MASTER <-> SLAVE sync: Finished with success

但是这样做的话,重启redis-002后又会复原,所以通常我们会直接修改redis-002配置文件redis.conf,在末尾加上slaveof 192.168.231.130 6379部分,就永久有效了。

现在我们往redis-001中写入数据,就可以从redis-002中查询出来了,我们来测试一下,往redis-001中写入key为name,value为osc的数据。

192.168.231.130:6379> set name osc
OK
192.168.231.130:6379> keys *
1) "name"
192.168.231.130:6379>

查询redis-002中的数据,会发现同样存在name的key,并且值为osc 

192.168.231.130:6380> keys *
1) "name"
192.168.231.130:6380> get name
"osc"
192.168.231.130:6380>

到目前为止,redis主从复制已经配置成功了,接下来就要开始重点工作,配置双机热备。

redis+sentinel双机热备

1.理论概念

    双机热备特指基于高可用系统中的两台服务器的热备(或高可用),因两机高可用在国内使用较多,故得名双机热备,双机高可用按工作中的切换方式分为:主-备方式(Active-Standby方式)和双主机方式(Active-Active方式),主-备方式即指的是一台服务器处于某种业务的激活状态(即Active状态),另一台服务器处于该业务的备用状态(即Standby状态)。而双主机方式即指两种不同业务分别在两台服务器上互为主备状态(即Active-Standby和Standby-Active状态)。

大白话就是,当主服务器挂了之后,从服务器立马切换为主服务器继续工作,当原先主服务器修复完善启动后,会自动充当从服务器的角色继续工作。这样就很好的避免了,由于一台主机出现故障,系统挂点的现象出现。

Sentinel(哨兵)是用于监控redis集群中Master状态的工具,已经集成在redis官方版本中,可以直接配置使用。

2.Sentinel命令

       PING :返回 PONG 。
       SENTINEL masters :列出所有被监视的主服务器,以及这些主服务器的当前状态;
       SENTINEL slaves <master name> :列出给定主服务器的所有从服务器,以及这些从服务器的当前状态;
       SENTINEL get-master-addr-by-name <master name> : 返回给定名字的主服务器的 IP 地址和端口号。 如果这个主服务器正在执行故障转移操作, 或者针对这个主服务器的故障转移操作已经完成, 那么这个命令返回新的主服务器的 IP 地址和端口号;
       SENTINEL reset <pattern> : 重置所有名字和给定模式 pattern 相匹配的主服务器。 pattern 参数是一个 Glob 风格的模式。 重置操作清楚主服务器目前的所有状态, 包括正在执行中的故障转移, 并移除目前已经发现和关联的, 主服务器的所有从服务器和 Sentinel ;
       SENTINEL failover <master name> : 当主服务器失效时, 在不询问其他 Sentinel 意见的情况下, 强制开始一次自动故障迁移。

客户端可以通过SENTINEL get-master-addr-by-name <master name>获取当前的主服务器IP地址和端口号,以及SENTINEL slaves <master name>获取所有的Slaves信息

3.双机热备配置

a.关闭redis-001与redis-002

b.在redis-001和redis-002配置sentinel.conf中加上以下配置信息:

sentinel monitor mymaster 192.168.231.130 6379 1

c.修改redis-002 sentinel.conf监听端口:

​$ cd /usr/tools/redis-002/
$ vim sentinel.conf
...找到port 26379改为26380...
port 26380

d.分别启动redis-001(主)与redis-002(从),redis 服务和sentinel服务

​$ cd /usr/tools/redis-002/
$ ./src/redis-server redis.conf
$ ./src/redis-sentinel sentinel.conf
​$ cd /usr/tools/redis-001/
$ ./src/redis-server redis.conf
$ ./src/redis-sentinel sentinel.conf

此时在主从redis,sentinel控制台会出现以下信息:

14677:X 09 Oct 14:04:49.633 # Sentinel ID is 7b8fdc1e5e47426b0d62a3ddd22ede0fd712f452
14677:X 09 Oct 14:04:49.633 # +monitor master mymaster 192.168.231.130 6379 quorum 1
14677:X 09 Oct 14:04:49.634 * +slave slave 192.168.231.130:6380 192.168.231.130 6380 @ mymaster 192.168.231.130 6379
14677:X 09 Oct 14:05:53.727 * +sentinel sentinel 31e660153984b606951c564395bdc8e193943f0b 192.168.231.130 26380 @ mymaster 192.168.231.130 6379

e.测试结果:

连接主服务器sentinel,注意端口是sentinel.conf中配置的端口

根据前面描述的sentinel命令查询主服务器信息:

192.168.231.130:26379> SENTINEL masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "192.168.231.130"
    5) "port"
    6) "6379"
    7) "runid"
    8) "fafb94fe9bff119e8a97f9183e3bcb5561933631"
    9) "flags"
   10) "master"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "671"
   19) "last-ping-reply"
   20) "671"
   21) "down-after-milliseconds"
   22) "10000"
   23) "info-refresh"
   24) "4904"
   25) "role-reported"
   26) "master"
   27) "role-reported-time"
   28) "205675"
   29) "config-epoch"
   30) "0"
   31) "num-slaves"
   32) "1"
   33) "num-other-sentinels"
   34) "1"
   35) "quorum"
   36) "1"
   37) "failover-timeout"
   38) "180000"
   39) "parallel-syncs"
   40) "1"
192.168.231.130:26379>

查询从服务器信息:

192.168.231.130:26379> SENTINEL slaves mymaster
1)  1) "name"
    2) "192.168.231.130:6380"
    3) "ip"
    4) "192.168.231.130"
    5) "port"
    6) "6380"
    7) "runid"
    8) "feabcfa65e69778e877ca0bd95adb9d642f6522f"
    9) "flags"
   10) "slave"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "928"
   19) "last-ping-reply"
   20) "928"
   21) "down-after-milliseconds"
   22) "10000"
   23) "info-refresh"
   24) "7332"
   25) "role-reported"
   26) "slave"
   27) "role-reported-time"
   28) "388802"
   29) "master-link-down-time"
   30) "0"
   31) "master-link-status"
   32) "ok"
   33) "master-host"
   34) "192.168.231.130"
   35) "master-port"
   36) "6379"
   37) "slave-priority"
   38) "100"
   39) "slave-repl-offset"
   40) "472844"
192.168.231.130:26379>

现在,我们来关闭端口为6379主redis-001服务器,看看会出现什么情况,此时redis-002控制台会出现以下信息:

14735:S 09 Oct 14:15:47.618 # Error condition on socket for SYNC: Connection refused
14735:S 09 Oct 14:15:48.628 * Connecting to MASTER 192.168.231.130:6379
14735:S 09 Oct 14:15:48.628 * MASTER <-> SLAVE sync started
14735:S 09 Oct 14:15:48.628 # Error condition on socket for SYNC: Connection refused
14735:S 09 Oct 14:15:49.638 * Connecting to MASTER 192.168.231.130:6379
14735:S 09 Oct 14:15:49.638 * MASTER <-> SLAVE sync started
14735:S 09 Oct 14:15:49.638 # Error condition on socket for SYNC: Connection refused
14735:S 09 Oct 14:15:50.648 * Connecting to MASTER 192.168.231.130:6379
14735:S 09 Oct 14:15:50.648 * MASTER <-> SLAVE sync started
14735:S 09 Oct 14:15:50.648 # Error condition on socket for SYNC: Connection refused
14735:S 09 Oct 14:15:51.659 * Connecting to MASTER 192.168.231.130:6379
14735:S 09 Oct 14:15:51.659 * MASTER <-> SLAVE sync started
14735:S 09 Oct 14:15:51.659 # Error condition on socket for SYNC: Connection refused
14735:S 09 Oct 14:15:52.669 * Connecting to MASTER 192.168.231.130:6379
14735:S 09 Oct 14:15:52.669 * MASTER <-> SLAVE sync started
14735:S 09 Oct 14:15:52.669 # Error condition on socket for SYNC: Connection refused
14735:M 09 Oct 14:15:53.459 * Discarding previously cached master state.
14735:M 09 Oct 14:15:53.459 * MASTER MODE enabled (user request from 'id=5 addr=192.168.231.130:53187 fd=7 name=sentinel-7b8fdc1e-cmd age=23 idle=0 flags=x db=0 sub=0 psub=0 multi=3 qbuf=0 qbuf-free=32768 obl=36 oll=0 omem=0 events=r cmd=exec')
14735:M 09 Oct 14:15:53.463 # CONFIG REWRITE executed with success.

从日志可以看出,服务器会经过多次连接主服务器失败后,判定主服务器故障,会对配置文件进行重写(CONFIG REWRITE executed with success),我们再去看看从服务器的配置文件redis.conf,会发现之前在末尾加上的slaveof 192.168.231.130 6379不见了,这就说明当sentinel监测到主服务器挂掉之后,自动将从服务器切换为主服务器。

我们再来看看主从服务器sentinel控制台输出了信息:

主sentinel:

14677:X 09 Oct 14:15:54.384 # +promoted-slave slave 192.168.231.130:6380 192.168.231.130 6380 @ mymaster 192.168.231.130 6379
14677:X 09 Oct 14:15:54.384 # +failover-state-reconf-slaves master mymaster 192.168.231.130 6379
14677:X 09 Oct 14:15:54.456 # +failover-end master mymaster 192.168.231.130 6379
14677:X 09 Oct 14:15:54.456 # +switch-master mymaster 192.168.231.130 6379 192.168.231.130 6380
14677:X 09 Oct 14:15:54.456 * +slave slave 192.168.231.130:6379 192.168.231.130 6379 @ mymaster 192.168.231.130 6380
14677:X 09 Oct 14:16:04.479 # +sdown slave 192.168.231.130:6379 192.168.231.130 6379 @ mymaster 192.168.231.130 6380

从sentinel:

14688:X 09 Oct 14:15:53.223 # +sdown master mymaster 192.168.231.130 6379
14688:X 09 Oct 14:15:53.223 # +odown master mymaster 192.168.231.130 6379 #quorum 1/1
14688:X 09 Oct 14:15:53.223 # Next failover delay: I will not start a failover before Sun Oct  9 14:21:53 2016
14688:X 09 Oct 14:15:54.461 # +config-update-from sentinel 7b8fdc1e5e47426b0d62a3ddd22ede0fd712f452 192.168.231.130 26379 @ mymaster 192.168.231.130 6379
14688:X 09 Oct 14:15:54.461 # +switch-master mymaster 192.168.231.130 6379 192.168.231.130 6380
14688:X 09 Oct 14:15:54.461 * +slave slave 192.168.231.130:6379 192.168.231.130 6379 @ mymaster 192.168.231.130 6380
14688:X 09 Oct 14:16:04.483 # +sdown slave 192.168.231.130:6379 192.168.231.130 6379 @ mymaster 192.168.231.130 6380

从上面日志信息可以看出,主从确实已经切换成功了,最后我们来看看实际情况是不是那样的,打开命令行执行查询主从信息命令,看看会出现什么结果:

192.168.231.130:26379> SENTINEL get-master-addr-by-name mymaster
1) "192.168.231.130"
2) "6380"
192.168.231.130:26379>
192.168.231.130:26379> SENTINEL masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "192.168.231.130"
    5) "port"
    6) "6380"
    7) "runid"
    8) "bb4fe3dece04db30c29f6650f1edd4d3689da751"
    9) "flags"
   10) "master"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "14"
   19) "last-ping-reply"
   20) "14"
   21) "down-after-milliseconds"
   22) "10000"
   23) "info-refresh"
   24) "4648"
   25) "role-reported"
   26) "master"
   27) "role-reported-time"
   28) "847746"
   29) "config-epoch"
   30) "1"
   31) "num-slaves"
   32) "1"
   33) "num-other-sentinels"
   34) "1"
   35) "quorum"
   36) "1"
   37) "failover-timeout"
   38) "180000"
   39) "parallel-syncs"
   40) "1"
192.168.231.130:26379>

到这里基本已经部署完毕了,再去启动原先主服务器redis-001,会发现此时的redis-001变成了从服务器,接下来的内容由于与前面重复较多,我就不演示了。

注意事项

1.一步一步来,先配置主从复制,再配置主从切换

2.启动顺序不要弄错了,先启动主服务器的redis与sentinel,再启动从服务器redis与sentinel,如果遇到失败情况,由于sentinel启动后会自动修改和生成部分配置信息,为避免冲突浪费时间,建议直接删除配置文件,重新配置。

3.如果redis有密码的话,需要在主从服务器redis.conf中都加上:

masterauth <password>

以及在主从服务器sentinel.conf加上:

sentinel auth-pass mymaster <password>

两者密码一致。

4.daemonize yes,启用保护进程
protected-mode no,关闭保护模式

另附

具体程序代码修改部分,可以参考《JedisSentinelPool的相关配置与操作》

《福利送上,未满十八岁勿点》

© 著作权归作者所有

AlanVision
粉丝 114
博文 47
码字总数 16858
作品 0
深圳
程序员
私信 提问
加载中

评论(8)

AlanVision
AlanVision

引用来自“aspboy”的评论

不错

谢谢
aspboy
aspboy
不错
AlanVision
AlanVision

引用来自“cpanmac”的评论

请问sentinel模式下应用连接redis是通过哨兵连接嘛
嗯,是的,具体程序的修改内容,可参照这篇文章:https://my.oschina.net/u/2249566/blog/756319
c
cpanmac
请问sentinel模式下应用连接redis是通过哨兵连接嘛
AlanVision
AlanVision

引用来自“开源中国总理”的评论

如果某台机器挂了呢,这样主sentinel也挂了,怎么办???

引用来自“开源中国OSC”的评论

我测试过,主sentinel先挂了,是没办法实现主从切换的,毕竟监听程序都没了

引用来自“开源中国总理”的评论

建议你看看SSDB,用nginx做TCP代理到后端的多个SSDB上,感觉比你这个要强。
嗯,比这个强的有很多,而且redis的集群方案也有很多,前面也已经说了,我这里只是实现了最适合我们目前现状的方案,另外keepalive+redis完全可以实现你说的情景,再进一步,可以用redis官方推荐的集群方案
沙-漠
沙-漠

引用来自“开源中国总理”的评论

如果某台机器挂了呢,这样主sentinel也挂了,怎么办???

引用来自“开源中国OSC”的评论

我测试过,主sentinel先挂了,是没办法实现主从切换的,毕竟监听程序都没了
建议你看看SSDB,用nginx做TCP代理到后端的多个SSDB上,感觉比你这个要强。
AlanVision
AlanVision

引用来自“开源中国总理”的评论

如果某台机器挂了呢,这样主sentinel也挂了,怎么办???
我测试过,主sentinel先挂了,是没办法实现主从切换的,毕竟监听程序都没了
沙-漠
沙-漠
如果某台机器挂了呢,这样主sentinel也挂了,怎么办???
JedisSentinelPool的相关配置与操作

前面文章《一步步实现redis+sentinel双机热备》中已经分享了如何配置使用redis自带监听程序sentinel实现双机热备,这篇文章将继续分享,客户端程序需要做哪些调整。 Spring配置文件 Redis配置...

OSC一霸
2016/10/10
733
1
关于双机热备,你该知道那些问题?

双机热备这一概念包括了广义与狭义两种意义。 从广义上讲,就是对于重要的服务,使用两台服务器,互相备份,共同执行同一服务。当一台服务器出现故障时,可以由另一台服务器承担服务任务,从...

抢地主
2016/06/15
58
0
华为USG防火墙及NGFW高可用性的规划与实施详解

华为USG防火墙及NGFW高可用性的规划与实施详解 课程目标: 该课程程为卷B,它紧接卷A所描述的基础内容,开始进入防火墙的高可性的规划与实施,本课程卷B的核心目标是:一、从真正意义上去理解...

kingsir827
2016/04/04
0
0
邮件服务器架设-双机热备方案

双机热备针对的是服务器的临时故障所做的一种备份技术,通过双机热备,来避免长时间的服务中断,保证系统长期、可靠的服务。本方案将详细介绍邮件服务器双机热备的解决方案,以TurboMail邮件...

月亮湖泊
2009/11/05
252
0
基于nginx实现web服务器的双机热备

1.适用场景 对于部署重要的服务,会使用两台服务器,互相备份,共同执行同一服务。当一台服务器出现故障时,可以由另一台服务器承担服务任务,从而在不需要人工干预的情况下,自动保证系统能...

_Reality
2017/12/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

vsftp 安装

1、安装命令:yum install vsftpd 2、启动命令:systemctl start vsftpd.service 查看状态命令:systemctl status vsftpd.service 停止命令:systemctl stop vsftpd.service 3、...

654476371
11分钟前
0
0
powershell 比较Excel文件内容

今天在工作中遇到一个问题,需要比较Excel文件中两列值有哪些不同: 实际上这两列数据比较多且大多数重复,上图只是举个简单的例子, 可以看出其中345是重复项,怎么找出来呢?用powershell实...

求神
17分钟前
3
0
如何通过ShareSDK的 Unity3D快速接入Android/iOS分享与授权

Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎;在游戏中...

MobService
19分钟前
1
0
手动实现 SpringMVC

先看整体架构 因为我们这个 MVC 框架要依赖 IOC/DI 容器,所以我们在 pom 文件里要将自己的 Spring 框架引入进来。 实现 MVC 的整体功能 首先我们定义两个 MVC 专用的注解,RequestMapping ...

编辑之路
24分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部