zoukankan      html  css  js  c++  java
  • centos LB负载均衡集群 三种模式区别 LVS/NAT 配置 LVS/DR 配置 LVS/DR + keepalived配置 nginx ip_hash 实现长连接 LVS是四层LB 注意down掉网卡的方法 nginx效率没有LVS高 ipvsadm命令集 测试LVS方法 第三十三节课

    centos   LB负载均衡集群 三种模式区别 LVS/NAT 配置  LVS/DR 配置  LVS/DR + keepalived配置  nginx ip_hash 实现长连接  LVS是四层LB  注意down掉网卡的方法  nginx效率没有LVS高  ipvsadm命令集  测试LVS方法 第三十三节课

    LVS核心模块就是IPVS,安装在Director上,Director就是一个路由器,他包含有完成lvs功能的路由表,通过这些路由表把用户请求分发到real server。
    同时,在Director上还要安装对realserver的监控模块LDirectord(LDirectord是heartbeat里面的一个插件,还需要perl-MailTools这个rpm包),这个模块用于监测各个real server服务的健康状况, 在real server不可用时把其从lvs路由表中剔除,在恢复时再重新加入

    LVS即使其中一台web服务器挂掉,LVS依然会把请求分发到挂掉的服务器,这是LVS的缺点

    LVS权重最大100 最小0


    用户的登录态的保持
    1、服务器间用共享存储
    2、用长连接,不允许会话切换web服务器,让会话保持在一台服务器


    服务器:session
    客户端:cookies

    三种模式区别

    $IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.100:80 -m -w 1  //-a增加一个real server  -m NAT模式 -g dr模式 -t tun模式  -w权重

    NAT模式:director负责接受请求和返回请求,realserver可以是任意操作系统,dr的vip和dip只需要不同网段就可以

    DR模式/TUN模式:返回请求不需要经过director,director只负责分发接受的请求,realserver只能是Unix like操作系统

    DR模式和TUN模式区别:TUN模式realserver和dr通信使用隧道(修改了ip包头),DR模式不使用隧道(修改MAC地址)

    三种模式都不需要公网IP,客户端,dr,realserver都在同一个内网里面都可以

    如果dr用公网ip,那么realserver的rip也要用公网ip

    dip:director ip

    rip:real server ip

    上半节课

    三种模式区别
    LVS/NAT 配置
    LVS/DR 配置

    下半节课

    LVS/DR + keepalived配置
    nginx ip_hash 实现长连接
    LVS是四层LB
    注意down掉网卡的方法
    nginx效率没有LVS高
    ipvsadm命令集

    NAT模式(Virtual server via NAT(VS-NAT))

    DR模式(Virtual Server via Direct Routing(VS-DR))

    TUN模式(Virtual server via IP tunneling(VS-TUN))

    常用的负载均衡开源软件有: nginx、lvs、keepalived
    商业的硬件负载设备: F5、Netscale

    1. LB、LVS介绍LB集群是load balance 集群的简写,翻译成中文就是负载均衡集群

    LVS是一个实现负载均衡集群的开源软件项目
    LVS架构从逻辑上可分为调度层(Director)、server集群层(Real server)和共享存储层

    LVS可分为三种工作模式: ( dr模式参考这篇文章 http://os.51cto.com/art/201105/264303.htm 这篇介绍的还是挺详细的: http://www.it165.net/admin/html/201401/2248.html )
    1、NAT NAT (调度器将请求的目标ip即vip地址改为Real server的ip, 返回的数据包也经过调度器,调度器再把源地址修改为vip)
    2、TUN   IP tunneling(调度器将请求来的数据包封装加密通过ip隧道转发到后端的real server上,而real server会直接把数据返回给客户端,而不再经过调度器)
    3、DR  Direct Routing(调度器将请求来的数据包的目标mac地址改为real server的mac地址,返回的时候也不经过调度器,直接返回给客户端)



    LVS最最常用的4种调度算法:
    1、轮询调度(Round Robin)(简称rr)
    2、加权轮询(Weighted Round Robin)(简称wrr)
    3、最少链接(least connection)(LC)  分配给现在最少链接那台机 
    4、加权最少链接(Weighted Least Connections)(WLC)
    等等 (其他算法,参考 http://www.aminglinux.com/bbs/thread-7407-1-1.html)

    2. LVS/NAT 配置
    三台服务器一台作为director, 两台作为real server
    Director 有一个ip (192.168.31.166) 和一个ip(192.168.21.166),

    两个real server上只有ip(192.168.21.100)和(192.168.21.101) 并且需要把两个real server的内网网关(eth0的gateway)设置为director的内网ip(192.168.21.166)

    检查一下网关是否成功设置  route -n  
    两个real server 上都安装httpd: yum install -y httpd
    Director上安装ipvsadm,  yum install -y ipvsadm
    Direcotr 上 vim /usr/local/sbin/lvs_nat.sh //增加:

    #! /bin/bash
    # director 服务器上开启路由转发功能: 
    echo 1 > /proc/sys/net/ipv4/ip_forward 
    # 关闭icmp的重定向
    echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
    echo 0 > /proc/sys/net/ipv4/conf/default/send_redirects
    echo 0 > /proc/sys/net/ipv4/conf/eth0/send_redirects
    echo 0 > /proc/sys/net/ipv4/conf/eth1/send_redirects
    
    # director 设置nat防火墙
    iptables -t nat -F
    iptables -t nat -X
    iptables -t nat -A POSTROUTING -s 192.168.21.0/24 -j MASQUERADE
    # director设置ipvsadm
    IPVSADM='/sbin/ipvsadm'
    $IPVSADM -C    //相当于iptables -F 清空规则
    $IPVSADM -A -t 192.168.31.166:80 -s lc -p 30   //-A增加dr  -s算法 默认rr轮询 lc最少链接 -p长链接 30秒 30秒内不停发送keepalive包给realserver 30秒后断开链接
    $IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.100:80 -m -w 1  //-a增加一个real server  -m 使用NAT模式 -g dr模式 -t tun模式  -w权重
    $IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.101:80 -m -w 1

    192.168.31.166  VIP

    192.168.21.166 DIP

    192.168.21.100 RIP

    192.168.21.101 RIP

    192.168.31.x 

    192.168.21.x 

    直接运行这个脚本就可以完成lvs/nat的配置了:
    /bin/bash /usr/local/sbin/lvs_nat.sh
    通过浏览器测试两台机器上的httpd内容

    查看一下规则

    iptables -nvL  -t nat

    查看一下ipvsadm规则

    ipvsadm -l
    ipvsadm -ln

    在客户端进行测试

    Linux客户端

    for i in `seq 1 100`; do curl 192.168.31.166;sleep 1;done

    Windows客户端

     在浏览器输入  192.168.31.166

    修改了规则需要重新执行一下

    vi /usr/local/sbin/lvs_nat.sh   //修改规则
    sh /usr/local/sbin/lvs_nat.sh  //重新执行脚本,使生效

     

    3. LVS/DR 配置

    每个realserver返回请求不需要经过director,director只负责分发接受的请求

    DR需要安装ipvsadm

    RS不需要安装ipvsadm


    三台机器:

    director(eth0:192.168.31.166, vip eth0:0: 192.168.31.110) vip不需要配置i,只需要写在脚本里就可以
    real server1(eth0 rip: 192.168. 31.100, vip lo:0: 192.168.31.110)
    real server2(eth0 rip: 192.168.31.101, vip lo:0: 192.168.31.110)
    Director 上 vim /usr/local/sbin/lvs_dr.sh //增加

    #! /bin/bash
    echo 1 > /proc/sys/net/ipv4/ip_forward
    ipv=/sbin/ipvsadm
    vip=192.168.31.110
    rs1=192.168.31.100 
    rs2=192.168.31.101
    ifdown eth0:0  //先down掉eth0:0 ,不然重新执行/usr/local/sbin/lvs_dr.sh 脚本会报网卡已启动
    ifconfig eth0:0 $vip broadcast $vip netmask 255.255.255.255 up //绑定vip netmask 表示无网段 注意机器上是否有eth0
    route add -host $vip dev eth0:0 //加个路由
    $ipv -C
    $ipv -A -t $vip:80 -s wrr
    $ipv -a -t $vip:80 -r $rs1:80 -g -w 1 //-g表示DR模式
    $ipv -a -t $vip:80 -r $rs2:80 -g -w 1


    两台rs上:vim /usr/local/sbin/lvs_dr_rs.sh
    #! /bin/bash
    vip=192.168.31.110
    ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up   //注意这里绑定的是lo 回环地址
    route add -host $vip 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


    关于arp_ignore和 arp_announce 参考:http://www.cnblogs.com/lgfeng/archive/2012/10/16/2726308.html

    然后director上执行: bash /usr/local/sbin/lvs_dr.sh
    两台rs上执行: bash /usr/local/sbin/lvs_dr_rs.sh
    Windows下浏览器测试访问

    测试

    测试LVS 
    机器1
    echo "rs1rs1rs1rs1" >/usr/share/nginx/html/index.html
    机器2
    echo "rs2rs2rs2rs2" >/usr/share/nginx/html/index.html


    下半节课 


    4. LVS/DR + keepalived配置

    keepalived可以帮助LVS检测后端服务器的存活,将请求只转发到存活的机器

    keepalived的诞生本来是为LVS而设计的,后来加入了VRRP协议


    注意:前面虽然我们已经配置过一些操作,但是下面我们使用keepaliave操作和之前的操作是有些冲突的,所以若是之前配置过DR,请首先做如下操作

    dr上执行:

    $ipv -C   //清空规则
    $ifdown eth0:0

    前面的lvs虽然已经配置成功也实现了负载均衡,但是我们测试的时候发现,当某台real server把httpd进程停掉,那么director照样会把请求转发过去,这样就造成了某些请求不正常。所以需要有一种机制用来检测real server的状态,这就是keepalived。它的作用除了可以检测rs状态外,还可以检测备用director的状态,也就是说keepalived可以实现ha集群的功能,当然了也需要一台备用director.
    主备director都需要安装一下keepalived软件和ipvsadm,需要先安装epel扩展源

    yum install -y keepalived
    yum install -y ipvsadm


    安装好后,编辑配置文件
    vim /etc/keepalived/keepalived.conf //加入如下:

    vrrp_instance VI_1 {
    state MASTER #备用服务器上为 BACKUP
    interface eth0
    virtual_router_id 51
    priority 100 #备用服务器上为90
    advert_int 1
    authentication {
    auth_type PASS  #跟heartbeat一样要指定加密方式和密码
    auth_pass 1111
    }
    virtual_ipaddress {
    192.168.31.110   #直接取192.168.31.110这个LVS的vip作为keepalived的vip而不是另取一个新的vip
    }
    }
    virtual_server 192.168.31.110 80 { #直接取192.168.31.110这个LVS的vip作为keepalived的vip而不是另取一个新的vip
    delay_loop 6 #(每隔6秒查询realserver状态)
    lb_algo wlc #(lvs 算法)
    lb_kind DR #(Direct Route)
    persistence_timeout 30 #(同一IP的连接30秒内被分配到同一台realserver)
    protocol TCP #(用TCP协议检查realserver状态)
    
    real_server 192.168.31.100 80 {
    weight 100 #(权重)
    TCP_CHECK {
    connect_timeout 10 #(10秒无响应超时)
    nb_get_retry 3
    delay_before_retry 3
    connect_port 80
    }
    }
    real_server 192.168.31.101 80 {
    weight 100
    TCP_CHECK {
    connect_timeout 10
    nb_get_retry 3
    delay_before_retry 3
    connect_port 80
    }
    }
    }

    以上为主director的配置文件,从director的配置文件只需要修改

    state MASTER -> state BACKUP
    priority 100 -> priority 90

    使用ip addr 查看vip是否已经启动

    ip addr

    配置完keepalived后,需要开启端口转发(主从都要做):
    echo 1 > /proc/sys/net/ipv4/ip_forward
    然后,两个rs上执行 /usr/local/sbin/lvs_dr_rs.sh 脚本
    最后,两个director上启动keepalived服务(先主后从):
    /etc/init.d/keepalived start
    另外,需要注意的是,主从dr上启动keepalived服务会自动生成vip和ipvsadm规则,不需要再去执行dr里面的/usr/local/sbin/lvs_dr.sh 脚本。

    由于keepalived没有单独日志,如果有问题,需要看 /var/log/message 里面的错误

     

    两台rs上:vim /usr/local/sbin/lvs_dr_rs.sh
    #! /bin/bash
    vip=192.168.31.110
    ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up   //注意这里绑定的是lo 回环地址
    route add -host $vip 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

    sh  /usr/local/sbin/lvs_dr_rs.sh

    停止rs2上的nginx,dr不会将请求发到rs2

    /etc/init.d/nginx stop

    Removing service [192.168.31.101]:80 from VS virtual server [192.168.31.110]:80

    重新启动rs2上的nginx,dr会马上自动把请求发到rs2

    /etc/init.d/nginx start

    从上安装配置keepalived和ipvsadm

    scp -P 2200 /etc/keepalived/keepalived.conf   192.168.31.112:/etc/keepalived/keepalived.conf
    vi /etc/keepalived/keepalived.conf 
    state MASTER #备用服务器上为 BACKUP
    priority 100 #备用服务器上为90
    /etc/init.d/keepalived start
    
    tail /var/log/message
    ipvsadm -ln
    ip addr  //从上是没有vip的

    主从切换模式

    /etc/init.d/keepalived stop

    或者

    iptables -I OUTPUT  -d 224.0.0.18  -j DROP


    5.nginx ip_hash 实现长连接

    upstream test {
    ip_hash;
    server 192.168.31.100;
    server 192.168.31.101;
    }

    server {
    listen 80;
    server_name bbs.aaa.cn;

    location / {
    proxy_pass http://test/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    }

    支持下面负载均衡算法
    轮询
    加权轮询
    ip_hash
    URL_hash

    ip_hash的坏处,服务器宕机,nginx依然会把请求发到宕机那台机,除非用轮询才会转发到别的机器或者用down标记那个宕机机器
    # 正常情况下是由 tomcat3 来应答的,当 tomcat3 死掉后

        upstream bbs_server_pool {
           ip_hash;
           server 192.168.1.80:8080;
           server 192.168.1.80:8081;
           server 192.168.1.80:8082 down;
        }

    ip_hash的两个问题
    1、是否支持权重  ,不支持权重
    2、保持链接多长时间 ,不支持保持链接,只是根据来源ip总是发送到某一台机

    测试

    测试NGINX
    机器1 
    echo "rs1rs1rs1rs1" >/usr/share/nginx/html/index.html 
    机器2 
    echo "rs2rs2rs2rs2" >/usr/share/nginx/html/index.html

    扩展学习:
    haproxy+keepalived http://blog.csdn.net/xrt95050/article/details/40926255
    nginx、lvs、haproxy比较 http://www.csdn.net/article/2014-07-24/2820837
    keepalived中自定义脚本 vrrp_script http://www.linuxidc.com/Linux/2012-08/69383.htm

    http://my.oschina.net/hncscwc/blog/158746
    nginx代理 http://www.apelearn.com/bbs/thread-64-1-1.html
    nginx长连接 http://www.apelearn.com/bbs/thread-6545-1-1.html


    LVS是四层LB

    NAT模式

    基于tcp/ip ,端口转发

    所以端口,后边的服务都可以随便改,LVS只负责转发端口

    httpd 可以改为nginx
    $IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.100:80 -m -w 1 可以改为$IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.100:8080 -m -w 1


    NAT模式

    权重设置

    # director设置ipvsadm
    IPVSADM='/sbin/ipvsadm'
    $IPVSADM -C
    $IPVSADM -A -t 192.168.31.166:80 -s wlc
    $IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.100:80 -m -w 2
    $IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.101:80 -m -w 10

    或者

    # director设置ipvsadm
    IPVSADM='/sbin/ipvsadm'
    $IPVSADM -C
    $IPVSADM -A -t 192.168.31.166:80 -s wrr
    $IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.100:80 -m -w 2
    $IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.101:80 -m -w 10


    注意down掉网卡的方法

    测试环境:centos6.6

    不要用ifconfig eth0 up/down 的方法

    ifconfig eth1:0 up/down 
    SIOCSIFFLAGS: 无法指定被请求的地址

    要用ifup/ifdown

    ifup eth1:0
    Determining if ip address 192.168.1.115 is already in use for device eth1...
    [root@steven network-scripts]# ifconfig

    另外,一个网卡多个ip,down掉一个ip并不会导致整个网卡down掉

    eth1 Link encap:Ethernet HWaddr 00:0C:29:01:D5:CB
    inet addr:192.168.1.106 Bcast:192.168.1.255 Mask:255.255.255.0
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:33032 errors:0 dropped:0 overruns:0 frame:0
    TX packets:4882 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:8892933 (8.4 MiB) TX bytes:421479 (411.6 KiB)

    eth1:0 Link encap:Ethernet HWaddr 00:0C:29:01:D5:CB
    inet addr:192.168.1.115 Bcast:192.168.1.255 Mask:255.255.255.0
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

    ---------------------------

    # ifdown eth1:0
    [root@steven network-scripts]# ifconfig
    eth1 Link encap:Ethernet HWaddr 00:0C:29:01:D5:CB
    inet addr:192.168.1.106 Bcast:192.168.1.255 Mask:255.255.255.0
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:33548 errors:0 dropped:0 overruns:0 frame:0
    TX packets:4938 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:8925293 (8.5 MiB) TX bytes:427603 (417.5 KiB)

    lo Link encap:Local Loopback
    inet addr:127.0.0.1 Mask:255.0.0.0
    UP LOOPBACK RUNNING MTU:65536 Metric:1
    RX packets:15 errors:0 dropped:0 overruns:0 frame:0
    TX packets:15 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:0
    RX bytes:2508 (2.4 KiB) TX bytes:2508 (2.4 KiB)


    nginx效率没有LVS高

    nginx: 匹配域名 匹配目录 匹配URL,工作在七层

    LVS:只能转发IP包,工作在四层

    各有优势 


    ipvsadm命令集

    ipvsadm -ln
    l:列出来
    n:数字显示

    $IPVSADM -C //相当于iptables -F 清空规则
    $IPVSADM -A //-A增加dr
    $IPVSADM -a //-a增加一个real server
    ipvsadm -ln //查看规则


    两个后端apache的动静分离、负载均衡

    http://www.apelearn.com/bbs/thread-64-1-1.html

    跟lnmp/lamp阶段复习差不多

    针对apache和nginx共同协作的网站架构,也可以根据动态内容和静态内容的请求来做负载均衡
    如:
            upstream apache.com{
                server  1.2.3.1:80;
                server  1.2.3.4:80;
            }
    location   ~*   .*.(php|phps|jsp)$ 
            {
                    proxy_pass  http://apache.com;
            }


    keepalived和VRRP协议
    http://blog.csdn.net/xrt95050/article/details/40926255
    VRRP通过竞选协议来实现虚拟路由器的功能,所有的协议报文都是通过IP多播(multicast)包(多播地址224.0.0.18)形式发送的。


    xiaohuazi: VRRP协议简介 在现实的网络环境中,两台需要通信的主机大多数情况下并没有直接的物理连接。对于这样的情况,它们之间路由怎样选择?主机如何选定到达目的主机的下一跳路由,这个问题通常的解决方法有二种:
    1、在主机上使用动态路由协议(RIP、OSPF等)
    2、在主机上配置静态路由


    VIP的飘动可以为我们解决很多问题,以前我试过使用ifup/ifdown的方式控制网卡的up/down来实现,这种方式有个小问题,就是每次VIP 飘动之后都要等上几十秒才能生效,感觉时间比较长,而且还要配合一些逻辑脚本才能很好地工作,有没有更好的方法呢?当然有,这就是本文的主角—— keepalived。


    负载均衡的发展历程
    http://mp.weixin.qq.com/s?__biz=MzI4NTA1MDEwNg==&mid=403078442&idx=2&sn=bd31fddfccafde520a2fb0060e9b6522&scene=0#wechat_redirect
    1996 F5成立
    1998 LVS项目成立
    2000 HAProxy项目成立
    2004 NGINX推出公共版本
    2004 F5推出TMOS平台
    2007 F5开始提供应用交付(ADC)产品
    负载平衡、SSL卸载、压缩优化、TCP连接优化

    (一)LVS的痛点
    LVS最常用的有NAT、DR以及新的FULL NAT模式。上图比较了几种常见转发模式的优缺点。

    我们认为LVS的每种模式都有其优点和缺点,但最大的问题是其复杂性。相信很多朋友看到这三种方式的优缺点、还有F5的单臂模式、双臂模式都会有云里雾里的感觉。

    (二)LVS集群的痛点




    雪上加霜的是咱们还需要考虑LVS的性能扩展和容灾方法,这使得整个方案更加的复杂。常见的有基于Keepalived的主备方式和ECMP两种。
    Keepalived主备模式设备利用率低;不能横向扩展;VRRP协议,有脑裂的风险。而ECMP的方式需要了解动态路由协议,LVS和交换机均需要较复杂配置;交换机的HASH算法一般比较简单,增加删除节点会造成HASH重分布,可能导致当前TCP连接全部中断;部分交换机的ECMP在处理分片包时会有BUG。


    基于DR转发方式
    LVS支持四种转发模式:NAT、DR、TUNNEL和FULLNAT(FULLNAT最近新加入的模式 还为合并到内核主线),其实各有利弊。Vortex在设计之初就对四种模式做了评估,最后发现在虚拟化的环境下DR方式在各方面比较平衡,并且符合我们追求极致性能的理念。
    DR方式最大的优点是绝佳的性能,只有request需要负载均衡器处理,response可以直接从后端服务器返回客户机,不论是吞吐还是延时都是最好的分发方式。
    其次,DR方式不像NAT模式需要复杂的路由设置,而且不像NAT模式当client和后端服务器处于同一个子网就无法正常工作。DR的这个特性使他特别合适作为内网负载均衡。
    此外,不像FULLNAT一样需要先修改源IP再使用 TOA 传递源地址,还得在负载均衡器DR和后端服务器上RS都编译非主线main line的Kernel Module,DR可以KISS(Keep It Simple, Stupid)地将源地址传递给后端服务器。

    最后,虚拟化环境中已经采用Overlay虚拟网络了,所以TUNNEL的方式变得完全多余。而DR方式最大的缺点:需要LB和后端服务器在同一个二层网络,而这在UCloud的虚拟化网络中完全不是问题。主流的SDN方案追求的正是大二层带来的无缝迁移体验,且早已采用各种优化手段(例如ARP代理)来优化大二层虚拟网络。


    重启指定网卡
    ifdown eth0 && ifup eth0


    重启除lo网卡的所有网卡
    ifdown --exclude=lo -a && sudo ifup --exclude=lo -a

    f

  • 相关阅读:
    SSH整合
    JQuery
    MVC框架与增强
    通用分页(二)
    通用分页(一)
    自定义标签
    反射(一)
    Xml解析作业与Xml建模andXml建模作业
    Xml与Map之间的相互转换
    Xml解析
  • 原文地址:https://www.cnblogs.com/MYSQLZOUQI/p/5079543.html
Copyright © 2011-2022 走看看