Redis sentinel哨兵集群的实现步骤


Posted in Redis onJuly 15, 2022

一、Redis sentinel哨兵集群概述

(1)Redis哨兵概述

*Sentinel 哨兵:这是一个分布式系统,该进程是用于监控Redis集群中Master主服务器的工作状态,在Master主服务器发生故障时,可以实现Master和Slave服务器的秒级切换,保证系统有一个Master主服务器,提供了Redis集群的高可用,在Reids2.6.版本时被加入,到2.8版本之后得到了稳定

Redis哨兵和Redis主从的区别:

Redis哨兵:主服务器出现故障后,会有一个从服务器代替主服务器

Redis主从:主服务器出现故障后,从服务器不会做任何事

Redis sentinel哨兵集群的实现步骤

(2)Redis哨兵的工作机制

哨兵只需要部署在master主服务器上即可

工作进程:

监控(Monitoring):哨兵通过流言协议(gossip protocols)会不断检查集群中每一台服务器是否运作正常

提醒(Notification):当哨兵监控的某个redis服务器出现问题时,哨兵可以通过API(应用程序接口)向管理员或者其他应用程序发送通知

自动故障转移(Automatic failover):在集群中如果有一个Master主服务器出现故障时,哨兵会通过投票协议(Agreement Protocols)开始一次自动故障迁移操作,他会选择一台数据较完整的Slave从服务器升级为主服务器,当客户端试图连接失效的Master主服务器时,集群也会向客户端返回新的Master主服务器的地址,使得集群可以使用现在的Master替换掉失效的Master。

Master和Slave切换后,Master的redis主配置文件、Slave的redis主配置文件和哨兵的配置文件的内容都会发生相应的改变,即原来的Master的redis主配置文件会多一行Slave服务器的配置,之后哨兵的监控目标就会改变到现在的Master主服务器上

Redis sentinel哨兵集群的实现步骤

(3)哨兵的三个定时监控任务

每隔10秒,每个Sentinel节点会向主节点和从节点发送info命令获取Redis数据节点的信息

作用:

通过向主节点执行info命令,获取从节点的信息,这也是为什么Sentinel节点不需要显式配置监控从节点。当有新的从节点加入时都可以立刻感知出来,当节点不可达或者故障转移后,可以通过info命令实时更新节点拓扑信息。

每隔1秒,每个Sentinel节点会向主节点、从节点、发送一条ping命令做一次心跳检测,来确认这些节点当前是否可达如果主节点挂掉,那么sentinel,就会从剩余的从节点选择一个数据比较完整来做主节点

二、部署Redis哨兵系统

(1)实验环境

系统 ip 主机名 Redis版本 端口 扮演角色
Centos7.4 192.168.100.202 master Redis-5.0.4 Redis:6379 Sentinel:26379 Master
Centos7.4 192.168.100.203 slave1 Redis-5.0.4 Redis:6379 Slave
Centos7.4 192.168.100.204 slave2 Redis-5.0.4 Redis:6379 Slave

(2)实验步骤 -在每台服务器上都安装Redis

安装步骤相同,主机名、ip不同,下面只写Master配置

[root@Centos7 ~]# hostnamectl set-hostname master
[root@Centos7 ~]# su
[root@master ~]# systemctl stop firewalld
[root@master ~]# setenforce 0
setenforce: SELinux is disabled
[root@master ~]# mount /dev/cdrom /mnt/
mount: /dev/sr0 写保护,将以只读方式挂载
mount: /dev/sr0 已经挂载或 /mnt 忙
       /dev/sr0 已经挂载到 /mnt 上
[root@master ~]# ll
总用量 1928
-rw-------. 1 root root    1264 1月  12 18:27 anaconda-ks.cfg
-rw-r--r--  1 root root 1966337 6月   9 01:16 redis-5.0.4.tar.gz
[root@master ~]# tar xf redis-5.0.4.tar.gz
[root@master ~]# cd redis-5.0.4
[root@master redis-5.0.4]# make
[root@master redis-5.0.4]# mkdir -p /usr/local/redis
[root@master redis-5.0.4]# cp /root/redis-5.0.4/src/redis-server /usr/local/redis/
[root@master redis-5.0.4]# cp /root/redis-5.0.4/src/redis-cli /usr/local/redis/
[root@master redis-5.0.4]# cp /root/redis-5.0.4/redis.conf  /usr/local/redis/ 
[root@master redis-5.0.4]# vim /usr/local/redis/redis.conf   #修改
。。。。。。
  68 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  69 bind 192.168.100.202  #修改为本机地址,如果为127.0.0.1就只能本机访问
  70 
。。。。。。
  87 # are explicitly listed using the "bind" directive.
  88 protected-mode no  #关闭redis的保护模式,如果为yes的话其他客户端就无法连接到此服务器
  89 
。。。。。。
 135 # Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
 136 daemonize yes  #开启redis的后台守护程序,即在redis开启之后是放在后台运行的
 137 
。。。。。。
 262 # Note that you must specify a directory here, not a file name.
 263 dir /usr/local/redis/rdb
 264 
。。。。。。
 506 #
 507 requirepass 123123  #去掉注释,修改redis的密码为123123
 508 
#保存退出
[root@slave2 redis-5.0.4]# mkdir /usr/local/redis/rdb
[root@master redis-5.0.4]# vim /etc/init.d/redis
#!/bin/sh
# chkconfig: 2345 80 90
# description: Start and Stop redis
#PATH=/usr/local/bin:/sbin:/usr/bin:/bin
REDISPORT=6379
EXEC=/usr/local/redis/redis-server
REDIS_CLI=/usr/local/redis/redis-cli
PIDFILE=/var/run/redis_6379.pid
CONF="/usr/local/redis/redis.conf"
AUTH="123123"
LISTEN_IP=$(netstat -utpln |grep redis-server |awk '{print $4}'|awk -F':' '{print $1}')

case "$1" in
    start)
        if [ -f $PIDFILE ]
        then
                echo "$PIDFILE exists, process is already running or crashed"
        else
                echo "Starting Redis server..."
                $EXEC $CONF
        fi
        if [ "$?"="0" ]
        then
              echo "Redis is running..."
        fi
        ;;
    stop)
        if [ ! -f $PIDFILE ]
        then
                echo "$PIDFILE does not exist, process is not running"
        else
                PID=$(cat $PIDFILE)
                echo "Stopping ..."
                $REDIS_CLI -h $LISTEN_IP -p $REDISPORT -a $AUTH SHUTDOWN
                while [ -x ${PIDFILE} ]
               do
                    echo "Waiting for Redis to shutdown ..."
                    sleep 1
                done
                echo "Redis stopped"
        fi
        ;;
   restart|force-reload)
        ${0} stop
        ${0} start
        ;;
  *)
    echo "Usage: /etc/init.d/redis {start|stop|restart|force-reload}" >&2
        exit 1
esac
[root@master redis-5.0.4]# chkconfig --add redis
[root@master redis-5.0.4]# chmod 755 /etc/init.d/redis
[root@master redis-5.0.4]# ln -s /usr/local/redis/* /usr/local/bin/
[root@master redis-5.0.4]# /etc/init.d/redis start 
Starting Redis server...
5233:C 09 Jun 2021 01:25:53.069 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
5233:C 09 Jun 2021 01:25:53.069 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=5233, just started
5233:C 09 Jun 2021 01:25:53.069 # Configuration loaded
Redis is running...
[root@master redis-5.0.4]# netstat -anpt | grep 6379
tcp        0      0 192.168.100.202:6379    0.0.0.0:*               LISTEN      5234/redis-server 1

-做redis主从

******(1)Master配置
[root@master redis-5.0.4]# vim /usr/local/redis/redis.conf #修改
。。。。。。
 292 #
 293  masterauth 123123  #配置主服务器密码,哨兵有一个问题,就是当主服务器坏掉,切换到从服务器时,原来的主服务器可以正常运行之后,再次加入集群是加不进去的,因为哨兵没有配置主服务器的密码,所以无法连接,所以在使用哨兵集群时,要把每台的主服务器密码都配置上,每台redis的密码最好都一样
 294 
。。。。。。
 456 #
 457  min-replicas-to-write 1 #设置slave服务器的数量,当slave服务器少于这个数量时,Master主服务器会停止接收客户端的一切写请求
 458  min-replicas-max-lag 10 #设置主服务器和从服务器之间同步数据的超时时间,当超过此时间时,master主服务器会停止客户端的一切写操作,单位为秒
 459 #
。。。。。。
[root@master redis-5.0.4]# /etc/init.d/redis restart   #重启redis
Stopping ...
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Redis stopped
Starting Redis server...
5291:C 09 Jun 2021 02:04:39.132 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
5291:C 09 Jun 2021 02:04:39.132 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=5291, just started
5291:C 09 Jun 2021 02:04:39.132 # Configuration loaded
Redis is running...

******(2)Slave1配置
[root@slave1 redis-5.0.4]# vim /usr/local/redis/redis.conf 
。。。。。。
 285 #
 286 replicaof 192.168.100.202 6379  #在从服务器上指定主服务器的ip和端口
 287 
。。。。。。
 292 #
 293 masterauth 123123  #指定主服务器上redis的密码
 294
。。。。。。
#保存退出
[root@slave redis-5.0.4]# /etc/init.d/redis restart  #重启服务
Stopping ...
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Redis stopped
Starting Redis server...
5304:C 09 Jun 2021 02:11:32.241 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
5304:C 09 Jun 2021 02:11:32.241 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=5304, just started
5304:C 09 Jun 2021 02:11:32.241 # Configuration loaded
Redis is running...

******(3)Slave2配置
[root@slave2 redis-5.0.4]# vim /usr/local/redis/redis.conf 
。。。。。。
 286  replicaof 192.168.100.204 6379
 287 
 288 # If the master is password protected (using the "requirepass" configuration
 289 # directive below) it is possible to tell the replica to authenticate before
 290 # starting the replication synchronization process, otherwise the master will
 291 # refuse the replica request.
 292 #
 293  masterauth 123123
 294 
。。。。。。
#保存退出
[root@slave2 redis-5.0.4]# /etc/init.d/redis restart 
Stopping ...
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Redis stopped
Starting Redis server...
5253:C 09 Jun 2021 17:50:25.680 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
5253:C 09 Jun 2021 17:50:25.680 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=5253, just started
5253:C 09 Jun 2021 17:50:25.680 # Configuration loaded
Redis is running...

******(3)验证主从是否成功
[root@master ~]# redis-cli -h 192.168.100.202 -a 123123
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.100.202:6379> set aaa bbb
OK
192.168.100.202:6379> set bbb ccc 
OK
192.168.100.202:6379> keys *
1) "aaa"
2) "bbb"

[root@slave1 ~]# redis-cli -h 192.168.100.203 -a 123123
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.100.203:6379> keys *
1) "bbb"
2) "aaa"
192.168.100.203:6379> set ttt fff
(error) READONLY You can't write against a read only replica.  #从服务器无法写入数据

[root@slave2 redis-5.0.4]# redis-cli -h 192.168.100.204 -a 123123
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.100.204:6379> keys *
1) "aaa"
2) "bbb"
192.168.100.204:6379> set ggg aaa
(error) READONLY You can't write against a read only replica.

#主从配置完成

-配置哨兵

******(1)在master上配置sentinel哨兵
[root@master ~]# cp redis-5.0.4/src/redis-sentinel /usr/local/redis/  #复制哨兵启动脚本
[root@master ~]# cp redis-5.0.4/sentinel.conf /usr/local/redis/  #复制哨兵配置文件
[root@master ~]# mkdir -p /var/redis/data  #创建日志文件存放位置	
[root@master ~]# vim /usr/local/redis/sentinel.conf   #修改哨兵配置文件
。。。。。。
 21 port 26379  #指定端口默认为26379
 22 
 23 # By default Redis Sentinel does not run as a daemon. Use 'yes' if you need it.
 24 # Note that Redis will write a pid file in /var/run/redis-sentinel.pid when
 25 # daemonized.
 26 daemonize yes  #yes为放在后台运行,使用no放在前台运行可以看到主从切换时候的信息
 27 
。。。。。。
 64 # unmounting filesystems.
 65 dir /var/redis/data  #指定日志存放位置,就是刚才创建的路径
 66 
。。。。。。
 83 # The valid charset is A-z 0-9 and the three characters ".-_".
 84 sentinel monitor mymaster 192.168.100.202  6379 1  #指定用户为mymaster,ip为202,端口为6379,1表示当有一台master出现故障时,就进行切换
 85 
 86 # sentinel a
。。。。。。
112 # Default is 30 seconds.
113 sentinel down-after-milliseconds mymaster 3000  #指定master的失效时间,单位为毫秒3000为3秒,表示master超过3秒没响应就判定为故障
114 
。。。。。。
145 # Default is 3 minutes.
146 sentinel failover-timeout mymaster 180000  #切换操作完成的超时时间,单位为毫秒180000为180秒,在主从切换超过这个时间就判定为切换失败
147 
148 # SCRIPTS EXE
。。。。。。
102 #
103  sentinel auth-pass mymaster 123123  #连接master和slave的密码
104 sentinel config-epoch mymaster  1  #切换后最多有多少节点可以于新的master进行同步数据
105 
#保存退出
[root@master ~]# /usr/local/redis/redis-sentinel /usr/local/redis/sentinel.conf  #启动哨兵
1118:X 09 Jun 2021 18:09:29.027 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1118:X 09 Jun 2021 18:09:29.027 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=1118, just started
1118:X 09 Jun 2021 18:09:29.027 # Configuration loaded
[root@master ~]# netstat -anpt | grep 26379
tcp        0      0 0.0.0.0:26379           0.0.0.0:*               LISTEN      1119/redis-sentinel 
tcp6       0      0 :::26379                :::*                    LISTEN      1119/redis-sentinel 
[root@master ~]# kill -9 1119  #先关闭哨兵
[root@master ~]# netstat -anpt | grep 26379
[root@master ~]# sed -i '26s/yes/no/g' /usr/local/redis/sentinel.conf  #修改为前台启动
[root@master ~]# /usr/local/redis/redis-sentinel /usr/local/redis/sentinel.conf  #再次开启哨兵,稍等一段时间会有提示
1129:X 09 Jun 2021 18:11:02.585 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1129:X 09 Jun 2021 18:11:02.585 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=1129, just started
1129:X 09 Jun 2021 18:11:02.585 # Configuration loaded
1129:X 09 Jun 2021 18:11:02.586 * Increased maximum number of open files to 10032 (it was originally set to 1024).
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 5.0.4 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 1129
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

1129:X 09 Jun 2021 18:11:02.586 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1129:X 09 Jun 2021 18:11:02.586 # Sentinel ID is fce7776020cf12792fd239f6f9d34f2d3fdef98c
1129:X 09 Jun 2021 18:11:02.586 # +monitor master mymaster 192.168.100.202 6379 quorum 1
1129:X 09 Jun 2021 18:18:04.434 * +reboot slave 192.168.100.204:6379 192.168.100.204 6379 @ mymaster 192.168.100.202 6379  #看到新增两条消息,从服务器增加了203和204主服务器时202
1129:X 09 Jun 2021 18:18:14.478 * +reboot slave 192.168.100.203:6379 192.168.100.203 6379 @ mymaster 192.168.100.202 6379

#哨兵配置完成

-测试哨兵的故障切换

******(1)把master服务器在开启一个终端,在新开启的终端中关闭redis,测试是否可以主从切换
[root@master ~]# /etc/init.d/redis stop 
Stopping ...
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Redis stopped

******(2)切换到开启哨兵的终端,查看新弹出的信息
1129:X 09 Jun 2021 18:20:36.588 # +failover-end master mymaster 192.168.100.202 6379
1129:X 09 Jun 2021 18:20:36.588 # +switch-master mymaster 192.168.100.202 6379 192.168.100.203 6379
1129:X 09 Jun 2021 18:20:36.588 * +slave slave 192.168.100.204:6379 192.168.100.204 6379 @ mymaster 192.168.100.203 6379  #发现主服务器变成了203
1129:X 09 Jun 2021 18:20:36.588 * +slave slave 192.168.100.202:6379 192.168.100.202 6379 @ mymaster 192.168.100.203 6379
1129:X 09 Jun 2021 18:20:39.607 # +sdown slave 192.168.100.202:6379 192.168.100.202 6379 @ mymaster 192.168.100.203 6379‘

******(3)在203上测试主从复制是否可以正常同步
[root@slave1 ~]# redis-cli -h 192.168.100.203 -a 123123
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.100.203:6379> keys *
1) "aaa"
2) "bbb"
192.168.100.203:6379> set yyy aaa
OK
192.168.100.203:6379> keys *
1) "yyy"
2) "aaa"
3) "bbb"

[root@slave2 redis-5.0.4]# redis-cli -h 192.168.100.204 -a 123123
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.100.204:6379> keys *  #发现同步成功
1) "yyy"
2) "bbb"
3) "aaa"

******(4)此时重新开启202的redis,并且查看哨兵的提示消息
[root@master ~]# /etc/init.d/redis start 
Starting Redis server...
1167:C 09 Jun 2021 18:23:39.756 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1167:C 09 Jun 2021 18:23:39.756 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=1167, just started
1167:C 09 Jun 2021 18:23:39.756 # Configuration loaded
Redis is running...

1129:X 09 Jun 2021 18:23:50.324 * +convert-to-slave slave 192.168.100.202:6379 192.168.100.202 6379 @ mymaster 192.168.100.203 6379   #提示增加了一台slave

******(5)在202的新终端上查看redis的数据是否成功同步
[root@master ~]# redis-cli -h 192.168.100.202 -a 123123
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.100.202:6379> keys *  #发现已经成功同步
1) "bbb"
2) "aaa"
3) "yyy"

#测试故障切换缓存,发现在master主机出现故障然后重新连接到集群后,master角色不会进行转移

-哨兵日志分析

#把哨兵放在前台运行时,日志信息会直接输出到终端上,放到后台运行时,日志会写到指定的路径中
+reset-master <instance details>   #当master被重置时.
+slave <instance details>  #当检测到一个slave并添加进slave列表时.
+failover-state-reconf-slaves <instance details> #Failover状态变为reconf-slaves状态时
+failover-detected <instance details> #当failover发生时
+slave-reconf-sent <instance details> #sentinel发送SLAVEOF命令把它重新配置时
+slave-reconf-inprog <instance details> #slave被重新配置为另外一个master的slave,但数据复制还未发生时。
+slave-reconf-done <instance details> #slave被重新配置为另外一个master的slave并且数据复制已经与master同步时。
-dup-sentinel <instance details> #删除指定master上的冗余sentinel时,当一个sentinel重新启动时,可能会发生这个事件
+sentinel <instance details> #当master增加了一个sentinel时。
+sdown <instance details> #进入SDOWN状态时;
-sdown <instance details> #离开SDOWN状态时。
+odown <instance details> #进入ODOWN状态时。
-odown <instance details> #离开ODOWN状态时。
+new-epoch <instance details>  #当前配置版本被更新时。
+try-failover <instance details> #达到failover条件,正等待其他sentinel的选举。
+elected-leader <instance details> #被选举为去执行failover的时候。
+failover-state-select-slave <instance details> #开始要选择一个slave当选新master时。
no-good-slave <instance details> #没有合适的slave来担当新master
selected-slave <instance details> #找到了一个适合的slave来担当新master
failover-state-send-slaveof-noone <instance details> #当把选择为新master的slave的身份进行切换的时候。
failover-end-for-timeout <instance details>   #failover由于超时而失败时。
failover-end <instance details> #failover成功完成时。
switch-master <master name> <oldip> <oldport> <newip> <newport> #当master的地址发生变化时。通常这是客户端最感兴趣的消息了。
+tilt #进入Tilt模式。
-tilt #退出Tilt模式。

到此这篇关于Redis sentinel哨兵集群的实现步骤的文章就介绍到这了,更多相关Redis sentinel哨兵集群内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!


Tags in this post...

Redis 相关文章推荐
Redis安装启动及常见数据类型
Apr 14 Redis
基于Redis实现分布式锁的方法(lua脚本版)
May 12 Redis
为Java项目添加Redis缓存的方法
May 18 Redis
5分钟教你docker安装启动redis全教程(全新方式)
May 29 Redis
redis客户端实现高可用读写分离的方式详解
Jul 04 Redis
在redisCluster中模糊获取key方式
Jul 09 Redis
关于redisson缓存序列化几枚大坑说明
Aug 04 Redis
Redis的字符串是如何实现的
Oct 24 Redis
Redis基本数据类型Set常用操作命令
Jun 01 Redis
Redis sentinel哨兵集群的实现步骤
Jul 15 Redis
Redis过期数据是否会被立马删除
Jul 23 Redis
Redis唯一ID生成器的实现
Jul 07 #Redis
Redis+AOP+自定义注解实现限流
Jun 28 #Redis
利用Redis实现点赞功能的示例代码
Jun 28 #Redis
一文教你快速生成MySQL数据库关系图
Jun 28 #Redis
Redis实现主从复制方式(Master&Slave)
Jun 21 #Redis
浅谈Redis变慢的原因及排查方法
使用Redis实现分布式锁的方法
Jun 16 #Redis
You might like
php上传、管理照片示例
2006/10/09 PHP
php仿ZOL分页类代码
2008/10/02 PHP
Windows下安装Memcached的步骤说明
2010/04/25 PHP
114啦源码(114la)不能生成地方房产和地方报刊问题4级页面0字节的解决方法
2012/01/12 PHP
Yii框架在页面输出执行sql语句以方便调试的实现方法
2014/12/24 PHP
php通过分类列表产生分类树数组的方法
2015/04/20 PHP
PHP+jQuery+Ajax实现用户登录与退出
2015/04/27 PHP
php unlink()函数使用教程
2018/07/12 PHP
多广告投放代码 推荐
2006/11/13 Javascript
XMLHTTPRequest的属性和方法简介
2010/11/23 Javascript
基于Jquery的淡入淡出的特效基础练习
2010/12/13 Javascript
jQuery实现鼠标滑过遮罩并高亮显示效果
2013/07/16 Javascript
JS实现时间格式化的方式汇总
2013/10/16 Javascript
教你快速搭建Node.Js服务器的方法教程
2017/03/30 Javascript
微信小程序使用progress组件实现显示进度功能【附源码下载】
2017/12/12 Javascript
vue cli 3.0 使用全过程解析
2018/06/14 Javascript
JS数组实现分类统计实例代码
2018/09/30 Javascript
JavaScript中this用法学习笔记
2019/03/17 Javascript
在vue中阻止浏览器后退的实例
2019/11/06 Javascript
python实现的系统实用log类实例
2015/06/30 Python
Python实现上下班抢个顺风单脚本
2018/02/07 Python
Python Flask框架模板操作实例分析
2019/05/03 Python
python和mysql交互操作实例详解【基于pymysql库】
2019/06/04 Python
Python3 requests文件下载 期间显示文件信息和下载进度代码实例
2019/08/16 Python
Python中sorted()排序与字母大小写的问题
2020/01/14 Python
使用Numpy对特征中的异常值进行替换及条件替换方式
2020/06/08 Python
python使用列表的最佳方案
2020/08/12 Python
python 使用openpyxl读取excel数据
2021/02/18 Python
英国在线自行车商店:Evans Cycles
2016/09/26 全球购物
法国家具及室内配件店:home24
2017/01/21 全球购物
英国领先的狗和宠物美容专家:Christies Direct
2017/04/03 全球购物
Dyson戴森波兰官网:Dyson.pl
2019/08/05 全球购物
化工工艺专业求职信
2013/09/22 职场文书
四风之害观后感
2015/06/09 职场文书
企业财务管理制度范本
2015/08/04 职场文书
2016年“12.3”国际残疾人日活动总结
2016/04/01 职场文书