热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

linux集群lvsdr模式(以Apache为例讲解)

本篇以Apache服务器为例讲述linux集群的lvsDR模式,dr与nat有相似处,本篇文章与上篇nat模式文章也有相似处。同样本篇先讲述lvs进行第7层健康检查情况,再讲述l

    本篇以Apache服务器为例讲述linux集群的lvs DR模式,dr与nat有相似处,本篇文章与上篇nat模式文章也有相似处。同样本篇先讲述lvs进行第7层健康检查情况,再讲述lvs进行第4层健康检查情况。同样都是集群技术,nat模式存在瓶颈,也就是瓶颈在HA分发器,而DR模式不存在瓶颈,可以极大提高网络带宽;不过NAT模式采用公网私有地址转换,nat模式节省稀缺的ipv4公网地址,而DR模式用到的ipv4地址都是公网地址(包括主从HA、各realserver用的ipv4都是公网ip),DR比较浪费地址;另外,dr模式中的主从HA服务器分别只要虚拟一个公网虚拟ip地址就行了,而nat模式中的主从HA服务器要分别各自模拟两个虚拟ip(一个是公网虚拟ip,一个是私网虚拟ip――供realserver作为网关用);dr模式中的各realserver服务器需要在lo地址上再绑定那个公网虚拟ip,而nat模式中的各realserver不需要这么做同样都是集群技术,lvs技术与nginx集群技术各有优缺点,场景不同选择方式也不一样,关于lvs与nginx的区别我已经专门写了一篇文章分析。本篇专门讲述lvs的DR技术

    实验环境:用4台linux虚机模拟,其中两台rhel5.6分别作为主从HA,上面配置keepalived和ipvsadm ;另外两台rhel4.6作为后端的realserver,上面搭建Apache服务器,此两台realserver模拟线上服务器。

    DR模式之所以不存在带宽瓶颈,是因为当realserver接收到HA分发的数据包,经过realserver处理后就直接发送到互联网上了,而不是像NAT模式那样realserver还要将处理好后的数据包再次转发给HA,然后HA还要返回给互联网(这是NAT模式形成瓶颈的原因)。见下面DR模式拓扑图,可以拿dr拓扑和nat拓扑作比较,其流量走向不同:

wKioL1OqWb6DUzBsAB0fPPbal8A180.jpg

    实验过程:

    将所有服务器的防火墙和selinux都关掉。用到的keepalived版本为keepalived-1.1.20.tar.gz,ipvsadm版本为ipvsadm-1.24.tar.gz。实验用的是DR模式rr算法。

    1.RS1的配置:

    在各realserver上只需搭建Apache、绑定虚拟ip到lo上以及取消arp转发功能等3大操作即可。

RS1的地址配成10.10.16.144

[root@RS1 ~]# vi /etc/sysconfig/network  ###修改主机名――修改hostname即可,一下的主机名都这么修改,修改保存后要重启服务器(reboot)才能生效。

    NETWORKING=yes

    HOSTNAME=RS1

[root@RS1 ~]# rpm -ivh httpd-2.0.52-38.ent.i386.rpm apr-util-0.9.4-21.i386.rpm httpd-suexec-2.0.52-38.ent.i386.rpm   ####安装Apache,由于这里realserver用的操作系统是rhel4.6,安装Apache操作和rhel5以上版本有所区别。

[root@RS1 ~]# vi /var/www/html/index.html   ###新建RS1 Apache主页面,作为用户访问测试用 

    RS1_ip:10.10.16.144

[root@RS1 ~]# vi /var/www/html/md5.html     ####在RS1的Apache目录里面新建md5.html网页,作为keepalived生成哈希值用,由于现在做的是lvs在7层做健康检查,要用到md5的哈希值验证

    ok,nimei!

[root@RS1 ~]# service httpd start

[root@RS1 ~]# chkconfig --level 35 httpd on

到这里,开始绑定虚拟公网ip到RS1的lo地址上,为了便于区别,这里绑定到lo:0,绑定虚拟公网ip目的是让realserver接收到的数据包经过处理后直接返回给互联网,而不是像nat模式那样还要将数据包返回给HA再由HA交给互联网。绑完公网ip后,还要取消arp响应,否则网络中会出现“这个公网ip对应多个mac地址回应数据”。可以用ifconfig lo:0 10.10.16.143绑到lo:0上,再将/proc/sys/net/ipv4/conf/lo/arp_ignore的值改为1,将/proc/sys/net/ipv4/conf/lo/arp_announce的值改为2,将/proc/sys/net/ipv4/conf/all/arp_ignore的值改为1,将/proc/sys/net/ipv4/conf/all/arp_announce的值改为2,这样就取消了了arp响应,这里可以写脚本将这两大步有条理的完成,脚本如下:

[root@RS1 ~]# vi realserver.sh   ###如果机器重启了,此脚本要重新运行一次,因为脚本里的添加ip的命令不是永久保存ip的

#!/bin/bash

#description: Config realserver


VIP=10.10.16.143

 

case "$1" in

start)

       /sbin/ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast 10.10.16.255 up

       /sbin/route add -host $VIP dev lo:0

       echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore

       echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce

       echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore

       echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

       sysctl -p >/dev/null 2>&1

       echo "RealServer Started !"

       ;;

stop)

       /sbin/ifconfig lo:0 down

       /sbin/route del $VIP >/dev/null 2>&1

       echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore

       echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce

       echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore

       echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce

       echo "RealServer Stoped !"

       ;;

*)

       echo "Usage: $0 {start|stop}"

       exit 1

esac

exit 0

[root@RS1 ~]# chmod 755 realserver.sh    ###给脚本赋可执行权限

[root@RS1 ~]# ./realserver.sh start      ####执行脚本,完成上述所述的两大步;也可以执行./realserver.sh stop取消lo:0和打开arp响应,调试的时候可以这么做 

到这里RS1的配置完成。


    2.RS2的配置

    RS2的配置和RS1的配置基本上相同,不同的是ip地址个Apache网页内容。

RS2的ip配成10.10.16.146

[root@RS2 ~]# rpm -ivh httpd-2.0.52-38.ent.i386.rpm apr-util-0.9.4-21.i386.rpm httpd-suexec-2.0.52-38.ent.i386.rpm 

[root@RS2 ~]# vi /var/www/html/index.html 

    RS2_ip:10.10.16.146

[root@RS2 ~]# cat /var/www/html/md5.html    ###注意到RS1、RS2的两个md5.html内容不一样,其生成对应的哈希值也不一样

ok,fuck!

[root@RS2 ~]# service httpd start

[root@RS2 ~]# chkconfig --level 35 httpd on

将RS1的realserver.sh脚本拷贝到RS2,赋权限执行start后,RS2的配置也完成。


    3.主HA的配置

    正如RS1和RS2的配置有很多相似处一样,主从HA的配置也有很多相似处。

[root@HA_master ~]# yum install gcc gcc-c++ openssl-devel kernel-devel -y

[root@HA_master ~]# tar zxf keepalived-1.1.20.tar.gz

[root@HA_master ~]# cd keepalived-1.1.20

[root@HA_master keepalived-1.1.20]# ./configure --syscOnfdir=/etc --with-kernel-dir=/usr/src/kernels/2.6.18-238.el5-i686/

[root@HA_master keepalived-1.1.20]# make &&make install

[root@HA_master ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf_bak  ###记得养成备份配置文件的习惯

[root@HA_master ~]# genhash -s 10.10.16.144 -p 80 -u /md5.html   ####分别获取两个realserver的哈希值,将此哈希值分别拷贝到各HA的keepalived配置文件中,该哈希值作为验证作用

MD5SUM = 5a1074db9fdd7753f086403e299c32ba

[root@HA_master ~]# genhash -s 10.10.16.146 -p 80 -u /md5.html

MD5SUM = 5e300b0518b2b3ef570559828ebf47ab

[root@HA_master ~]# vi /etc/keepalived/keepalived.conf   ####将keepalived的配置文件改成如下:

! Configuration File for keepalived


global_defs {

   notification_email {

     130562772@qq.com      ###可以将此处的邮箱地址改成自己的

   }

   notification_email_from 1305627792@qq.com

   smtp_server 192.168.200.1        ####可以将此处的发送邮箱ip地址改成自己公司的邮件服务器ip

   smtp_connect_timeout 30

   router_id LVS_DEVEL

}


vrrp_instance web {

    state MASTER       ####将此处状态标识成master,若是从的写成backup或slave,名称的选取没有限制

    interface eth0     ###将此处的网卡名称写成系统真实存在的网卡名(即eth0),如果有两个网卡,即增加了eth1,则将此处代码段整体复制,在新的代码段中将此处命名eth1

    virtual_router_id 24      ###为了保证通信不和其他机器冲突,将此处的id写成自己独特的,id最大值是255

    priority 100        ###将优先级也修改一下,默认是51,主HA的优先级要高于从HA,区分HA是主还是从靠的就是这里的优先级区分

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 1124      ###可以将此处的验证码修改成自己的,默认是1111

    }

    virtual_ipaddress {

        10.10.16.143      ###将此处的虚拟ip地址修改成预算好的虚拟公网ip(10.10.16.143)

    }

}


virtual_server 10.10.16.143 80 {        #####配置realserver部分

    delay_loop 6

    lb_algo rr        ####这里的算法采用rr算法,也可以选别的算法

    lb_kind DR        ####这里的模式写成DR,注意要大写

    persistence_timeout 0       ####默认的连接时间是50秒,这里为了实验效果更明显,写成0,实际生产中要选择一个适当的数值

    protocol TCP


    real_server 10.10.16.144 80 {       #####配置第一台realserver

        weight 1

        HTTP_GET {         ####这里的名称最好写成HTTP_GET,我试了好几个别的名字用来取代HTTP都没有成功。

            url {

              path /md5.html        ###验证哈希值的网页

              digest 5a1074db9fdd7753f086403e299c32ba         #####将上面获得的哈希值分别写在此处

            }

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

        }

    }


    real_server 10.10.16.146 80 {

        weight 1

        HTTP_GET {

            url {

              path /md5.html

              digest 5e300b0518b2b3ef570559828ebf47ab

            }

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

        }

    }

}

[root@HA_master ~]# cp /usr/local/sbin/keepalived /usr/sbin

[root@HA_master ~]# service keepalived start

[root@HA_master ~]# chkconfig --level 35 keepalived on

[root@HA_master ~]# ln -s /usr/src/kernels/2.6.18-238.el5-i686/ /usr/src/linux

[root@HA_master ~]# tar zxf ipvsadm-1.24.tar.gz

[root@HA_master ~]# cd ipvsadm-1.24

[root@HA_master ipvsadm-1.24]# make &&make install

    ok,到这里,keepalived和ipvsadm都安装好了,现在用ipvsadm工具测试能否在HA上检测到realserver状态:

wKioL1OqZiTBnOYAAAFNcvn-pEc923.jpg

    上面截图表明在主HA上能检测到realserver状态,也就是主HA配置完成。


    4.从HA的配置

[root@HA_slave ~]# yum install gcc gcc-c++ openssl-devel kernel-devel -y

[root@HA_slave ~]# tar zxf keepalived-1.1.20.tar.gz

[root@HA_slave ~]# cd keepalived-1.1.20

[root@HA_slave keepalived-1.1.20]# ./configure --syscOnfdir=/etc --with-kernel-dir=/usr/src/kernels/2.6.18-238.el5-i686/

[root@HA_slave keepalived-1.1.20]# make &&make install

[root@HA_slave ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf_bak

[root@HA_slave ~]# genhash -s 10.10.16.146 -p 80 -u /md5.html

MD5SUM = 5e300b0518b2b3ef570559828ebf47ab

[root@HA_slave ~]# genhash -s 10.10.16.144 -p 80 -u /md5.html

MD5SUM = 5a1074db9fdd7753f086403e299c32ba

    走到这里,可以将主HA的keepalived配置文件拷贝到从HA的keepalived配置文件目录下,稍加修改即可:

[root@HA_slave ~]# cat /etc/keepalived/keepalived.conf

! Configuration File for keepalived


global_defs {

   notification_email {

     130562772@qq.com

   }

   notification_email_from 1305627792@qq.com

   smtp_server 192.168.200.1

   smtp_connect_timeout 30

   router_id LVS_DEVEL

}


vrrp_instance web {

    state BACKUP    ####标识为备用状态

    interface eth0

    virtual_router_id 24

    priority 96   #####优先级修改为比主HA的小

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 1124

    }

    virtual_ipaddress {

        10.10.16.143

    }

}


virtual_server 10.10.16.143 80 {

    delay_loop 6

    lb_algo rr

    lb_kind DR

    persistence_timeout 0

    protocol TCP


    real_server 10.10.16.144 80 {

        weight 1

        HTTP_GET {

            url {

              path /md5.html

              digest 5a1074db9fdd7753f086403e299c32ba

            }

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

        }

    }


    real_server 10.10.16.146 80 {

        weight 1

        HTTP_GET {

            url {

              path /md5.html

              digest 5e300b0518b2b3ef570559828ebf47ab

            }

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

        }

    }

}

[root@HA_slave ~]# cp /usr/local/sbin/keepalived /usr/sbin

[root@HA_slave ~]# service keepalived start

[root@HA_slave ~]# chkconfig --level 35 keepalived on

[root@HA_slave ~]# ln -s /usr/src/kernels/2.6.18-238.el5-i686/ /usr/src/linux

[root@HA_slave ~]# tar zxf ipvsadm-1.24.tar.gz

[root@HA_slave ~]# cd ipvsadm-1.24

[root@HA_slave ipvsadm-1.24]# make &&make install

    到这里,也可以用ipvsadm工具检测一下realserver的状态,如下面截图:

wKiom1OqaM6AoMelAAFE9htZSBk734.jpg

    ok,上面截图表明在从HA上面也可以检测到realserver,到这里从HA的配置已经完成,也就是lvs DR模式对7层健康检查方法已经基本配置完成,下面做一些测试:

查看主HA的ip地址,发现eth0上绑定了“虚拟公网ip”:

wKiom1OqaW_gLhEgAAHnR_nE8lE232.jpg

    查看从HA的IP地址,发现没有绑定任何地址,因为只要主HA活着,从HA就一直做备胎,只有当主HA挂掉,从HA才会从备胎转换成master,但是当主HA故障修复完成后,从HA又会自动让位变成备胎,主HA依然是主HA:

wKiom1OqagmQSZX2AAG3vz1kbaY413.jpg

下面看一下RS1的ip地址状态,发现多了一个lo:0地址:

wKioL1OqajLhj9I8AAQfRBMyc5k333.jpg

再看一下RS2的ip地址,发现也多了一个lo:0地址:

wKioL1Oqal2QtkXhAAQEaPalPjM375.jpg

    现在用宿主机的3个浏览器分别访问10.10.16.143,发现返回的结果是来自RS1和RS2:

wKiom1OqatXgMIezAAHCOmASj6M113.jpg

    再在从HA服务器上用文本浏览器(curl)再次验证从10.10.16.143返回的值,发现当用户访问虚拟公网ip时,RS1、RS2都工作,此时HA实现的是分发轮询。

wKiom1OqayOSXoacAAIyfTqCiSA244.jpg

    现在让主HA网卡睡眠1分钟,即模拟主网卡故障,看从HA是否装换成主HA:

[root@HA_master ~]# ifdown eth0 &&sleep 60 &&ifup eth0

wKiom1OqbBLBd6k5AAHeXZpQA-k418.jpg

    发现从HA已顺利转成master,虚拟公网ip10.10.16.143跳到了从HA的eth0上面,这表明,主从HA有了配合,转成主HA的从HA会做主HA相同的工作,二者的功能相同。当主HA恢复时,从Ha又从主状态变为从状态。

    当RS1挂了,看看用户访问时,HA是否还会把数据包分发到坏的RS1上面:(可以让RS1网卡睡眠或停止工作、RS1停机、RS1 Apache挂掉等模拟RS1挂掉)

wKiom1Oqb1yC85BdAAM8WVq5Fww089.jpg

    发现当RS1挂了,HA不会把数据分发到RS1上了,而是将数据只分发到RS2上处理,如果有多台realserver则HA会把数据分发到除了RS1以外的其他realserver处理。当RS1恢复正常,则HA仍会将数据分发到RS1上处理,这说明了HA和realserver之间的配置是正确的,即HA的keepalived配置文件中关于realserver配置区域的配置是正确的。


    ok,lvs工作对7层检查检查的实验模拟完成(lvs只会工作在第四层,不会工作在第7层,但是lvs可以对第7层与第四层健康检查),现在模拟lvs对第4层健康检查模式的实验,其实这两种模式的配置基本相同,不同的是主从HA的keepalived的配置文件中关于realserver的配置,各realserver的配置不变。

下面是主HA的keepalived配置文件:

[root@HA_master ~]# cat /etc/keepalived/keepalived.conf

! Configuration File for keepalived


global_defs {

   notification_email {

     130562772@qq.com

   }

   notification_email_from 1305627792@qq.com

   smtp_server 192.168.200.1

   smtp_connect_timeout 30

   router_id LVS_DEVEL

}


vrrp_instance web {

    state MASTER

    interface eth0

    virtual_router_id 24

    priority 100

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 1124

    }

    virtual_ipaddress {

        10.10.16.143

    }

}


virtual_server 10.10.16.143 80 {

    delay_loop 6

    lb_algo rr

    lb_kind DR

    persistence_timeout 0

    protocol TCP


#    real_server 10.10.16.144 80 {

#        weight 1

#        HTTP_GET {

#            url {

#              path /md5.html

#              digest 5a1074db9fdd7753f086403e299c32ba

#            }

#            connect_timeout 3

#            nb_get_retry 3

#            delay_before_retry 3

#        }

#    }

#

#    real_server 10.10.16.146 80 {

#        weight 1

#        HTTP_GET {

#            url {

#              path /md5.html

#              digest 5e300b0518b2b3ef570559828ebf47ab

#            }

#            connect_timeout 3

#            nb_get_retry 3

#            delay_before_retry 3

#        }

#    }


      real_server 10.10.16.144 80 {

        weight 1

        TCP_CHECK{

          connect_port 80

          connect_timeout 3

          nb_get_retry 3

          delay_before_retry 3

         }

     }


    real_server 10.10.16.146 80 {

        weight 1

        TCP_CHECK{

          connect_port 80

          connect_timeout 3

          nb_get_retry 3

          delay_before_retry 3

        }

   }

}


下面是从HA的keepalived配置文件内容:

[root@HA_slave ~]# cat /etc/keepalived/keepalived.conf

! Configuration File for keepalived


global_defs {

   notification_email {

     130562772@qq.com

   }

   notification_email_from 1305627792@qq.com

   smtp_server 192.168.200.1

   smtp_connect_timeout 30

   router_id LVS_DEVEL

}


vrrp_instance web {

    state BACKUP

    interface eth0

    virtual_router_id 24

    priority 96

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 1124

    }

    virtual_ipaddress {

        10.10.16.143

    }

}


virtual_server 10.10.16.143 80 {

    delay_loop 6

    lb_algo rr

    lb_kind DR

    persistence_timeout 0

    protocol TCP


#    real_server 10.10.16.144 80 {

#        weight 1

#        HTTP_GET {

#            url {

#              path /md5.html

#              digest 5a1074db9fdd7753f086403e299c32ba

#            }

#            connect_timeout 3

#            nb_get_retry 3

#            delay_before_retry 3

#        }

#    }

#

#    real_server 10.10.16.146 80 {

#        weight 1

#        HTTP_GET {

#            url {

#              path /md5.html

#              digest 5e300b0518b2b3ef570559828ebf47ab

#            }

#            connect_timeout 3

#            nb_get_retry 3

#            delay_before_retry 3

#        }

#    }


      real_server 10.10.16.144 80 {

weight 1

TCP_CHECK{

 connect_port 80

 connect_timeout 3

 nb_get_retry 3

 delay_before_retry 3

}

     }


    real_server 10.10.16.146 80 {

weight 1

TCP_CHECK{

 connect_port 80

 connect_timeout 3

 nb_get_retry 3

 delay_before_retry 3

}

   }

}

    分别保存并重启keepalived,按照lvs对第7层健康检查模式去验证,会发现lvs对第4层健康检查仍然正常。这里的配置文件实际上就是把配置对第7层健康检查用的realserver区域注释掉,添加配置对第4层健康检查区域的代码。


    ok,到这里,使用rr算法的DR模式的LVS基于7层健康检查和基于4层健康检查的配置已经完成!

本文出自 “个人感受” 博客,谢绝转载!


推荐阅读
  • docker安装到基本使用
    记录docker概念,安装及入门日常使用Docker安装查看官方文档,在"Debian上安装Docker",其他平台在"这里查 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • linux下编译安装lnmp
    2019独角兽企业重金招聘Python工程师标准#######################安装依赖#####################安装必要的包:y ... [详细]
  • Linux内核那些事之连接跟踪
    “本文分析了Linux内核连接跟踪的关键实现”连接跟踪(也叫会话管理)是状态防火墙关键核心,也是很多网元设备必不可少的一部分。各厂商的实 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 开发笔记:Java是如何读取和写入浏览器Cookies的
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Java是如何读取和写入浏览器Cookies的相关的知识,希望对你有一定的参考价值。首先我 ... [详细]
  • 本文介绍了一个适用于PHP应用快速接入TRX和TRC20数字资产的开发包,该开发包支持使用自有Tron区块链节点的应用场景,也支持基于Tron官方公共API服务的轻量级部署场景。提供的功能包括生成地址、验证地址、查询余额、交易转账、查询最新区块和查询交易信息等。详细信息可参考tron-php的Github地址:https://github.com/Fenguoz/tron-php。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • ZABBIX 3.0 配置监控NGINX性能【OK】
    1.在agent端查看配置:nginx-V查看编辑时是否加入状态监控模块:--with-http_stub_status_module--with-http_gzip_stat ... [详细]
  • buildah是用来修改和改造镜像的工具,和podman同源,很多参数相似!只是podman用来纯粹运行容器,一个纯粹建造容器!1.获取容器并赋名buildah--nametest ... [详细]
  • HyperledgerComposer环境安装1.安装基本软件包**如果使用Linux安装HyperledgerComposer,请注意以下建议:以 ... [详细]
  • 在使用豆瓣OAuth登录接口时,我们需要发送这样的HTTPREQUEST请求:GETv2user~meHTTP1.1Host:https:api.douban.com ... [详细]
  • https:www.bilibili.comvideoav43996494?p61补充说明(修正前面代码存在问题):#先验框筛选defchoose_anchor_boxes(sel ... [详细]
  • 这篇文章主要讲解了“面向对象设计的六大原则是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究 ... [详细]
  • 【图解HTTP】第一章 了解web及网络基础
    [图解HTTP]了解Web及网络基础Web页面是如何呈现的?根据Web浏览器地址栏中指定的URL,Web浏览器从Web服务器端获取文件资源(resour ... [详细]
author-avatar
cathy522_788
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有