高并发 - 基于Keepalived的LVS实验

准备环境

vip:node01 192.168.79.101

lvs(主):node01 192.168.79.101 网卡: eth0
lvs(备):node04 192.168.79.104 网卡: eth0

nginx1:node02 192.168.79.102 网卡: eth3
nginx2:node03 192.168.79.103 网卡: eth3

RS中的服务

node02~node03:
1)修改内核:
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
2)设置隐藏的vip:
ifconfig lo:3 192.168.79.110 netmask 255.255.255.255

3)在node02 & node03上安装nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
## 解压
tar -xf nginx-1.16.1.tar.gz

## 安装编译工具及库文件
yum -y install gcc pcre-devel zlib-devel openssl openssl-devel

## 配置编译安装
cd nginx-1.16.1
./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_ssl_module

make & make install

## 分别修改index.html 加上ip 或内容区分是如台机,方便后续测试
vi /usr/local/nginx/html/index.html

## 启动nginx
./nginx

分别访问检查是否安装成功,如果服务正常开启,但主机访问不了,请检查防火墙
service iptables stop

http://192.168.79.102/
http://192.168.79.103/

安装ipvsadm & keepalived

在node01 & node04 安装 ipvsadm 和 keepalived

1
2
3
4
5
6
7
## 安装lvs的管理工具ipvsadm
yum install ipvsadm keepalived -y

## 配置
cd /etc/keepalived/
cp keepalived.conf keepalived.conf.bak
vi keepalived.conf

keepalived 配置文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
! Configuration File for keepalived

## 全局默认配置,发生故障时邮件通知
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.79.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}


## 虚拟路由冗余协议!
vrrp_instance VI_1 {
## state MASTER|BACKUP:当前节点在此虚拟路由器上的初始状态;只能有一个是MASTER,余下的都应该为BACKUP;
##node4 这里写 BACKUP
state MASTER
## 绑定为当前虚拟路由器使用的物理接口;
interface eth0
## 当前虚拟路由器的惟一标识,范围是0-255
virtual_router_id 51
## 当前主机在此虚拟路径器中的优先级;范围1-254;
## node4 这里小点,写 50
priority 100
## vrrp通告的时间间隔;
advert_int 1

## 设置认证
authentication {
auth_type PASS
auth_pass 1111
}

# 定义vip
virtual_ipaddress {
192.168.79.110/24 dev eth0 label eth0:1
}
}

virtual_server 192.168.79.110 80 {
## 每隔6秒查看realserver状态
delay_loop 6
## 调度算法改为轮询调度
lb_algo rr
# lvs工作模式为DR|NAT|TUN模式
lb_kind DR
nat_mask 255.255.255.0
# 同一IP 的连接50秒内被分配到同一台realserver(测试时改为0)
persistence_timeout 0
protocol TCP

## 定义realserver
real_server 192.168.79.102 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
## 三秒无响应超时
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
## 定义realserver
real_server 192.168.79.103 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
## 三秒无响应超时
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}

查看keepalived配置帮助文档

1
2
3
4
5
6
7
8
9
10
11
12
13
man 5 keepalived.conf

## 查看virtual_ipaddress 配置说明
virtual_ipaddress {
<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>
192.168.200.17/24 dev eth1
192.168.200.18/24 dev eth2 label eth2:1
}

## brd <IPADDR>: 桥接器地址
## dev <STRING>: 设备
## scope <SCOPE>: 权重值
## label <LABEL>: 标签

启动 & 验证 keepalived

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
## 启动keepalived
service keepalived start

## 检查网卡是否添加成功
ifconfig

## 主需要显示信息,主正常的时候备没有:
eth0:1 Link encap:Ethernet HWaddr 00:0C:29:6F:93:B0
inet addr:192.168.79.110 Bcast:0.0.0.0 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1


## 检查lvs内核模块的配置:
ipvsadm -ln

## 需要显示信息:
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.79.110:80 rr
-> 192.168.79.102:80 Route 1 0 0
-> 192.168.79.103:80 Route 1 0 0

## 查看负载记录:
ipvsadm -lnc

测试

* 用浏览器访问http://192.168.79.100 验证结果
* 分别停掉一台DR 或 主,备 再检验结果

将DR 的隐藏IP配置写成文件

创建lvsdr.sh,内容如下:

1
2
3
4
5
6
7
8
9
10
#!/bin/sh
VIP=192.168.79.110

# 限制arp请求
echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce

ifconfig lo:3 $VIP netmask 255.255.255.255

高并发 - 网络协议原理

计算机网络体系结构分层

OSI 七层模型 TCP/IP 概念层模型 功能 TCP/IP 协议
应用层 应用层 文件传输,电子邮件,文件服务 ,虚拟终端 TFTP,HTTP,SMTP,FTP,SNTP,DNS,Telnet
表示层 数据格式化,代码转换,数据加密 没有协议
会话层 解除或建立与的接点的联系 没有协议
传输层 传输层 提供端对端的接口 TCP,UDP
网络层 网络层 为数据包选择路由 IP,ICMP,RIP,OSPF,BCP,ICMP
数据链路层 链路层 传输有地址的帧以及错误检测功能 SLIP,CSLIP,PPP,ARP,RARP,MTU
物理层 以二进制数据型式在物理媒体上传数数据 ISO2110,IEEE802,IEEE802.2

阅读更多

高并发 - LVS的DR模型

理论基础

网卡上有IP和MAC地址,网卡一加电就会将自己公布出去,别的机器只能知道IP地址逻辑的会走ARP协议请求MAC地址。
Linux系统下 /proc 是虚拟目录,开机之后才会有的目录,里面放的内核及所有启动的进程,把里面的变量及参数抽象成文件,
修改文件的值相当于改了内核变量参数的值,目录中的文件的参数值一变,内核立即发生效果。
这些文件修改的时候不能用vi 命令去打开修改。因为会产生隐藏临时文件,只能echo 重定向去覆盖。

lo 回环接口,是内核上的虚拟网卡,虚拟网络接口,并非真实存在,并不真实地从外界接收和发送数据包,而是在系统内部接收和发送数据包,因此虚拟网络接口不需要驱动程序。lo回环地址

eth0 以太网接口,以太网接口与网卡对应,每个硬件网卡(一个MAC)对应一个以太网接口,其工作完全由网卡相应的驱动程序控制。
如果物理网卡只有一个,而却有eth1,eth2等,则可能存在无线网卡或多个虚拟网卡,虚拟网卡由系统创建或通过应用层程序创建,作用与物理网卡类似。

阅读更多

JVM - Class文件格式入门

-字节码指令集(汇编语言)
-内存管理:堆、栈、方法区等

常见的JVM实现

  • Hotspot - Oracl 官方
  • Jrockit - BEA,曾经号称世界上最快的JVM,被Oracle收购后,合并于hotspot
  • J9 - IBM
  • Microsoft VM
  • TaobaoVM - Hotspot 深度定制版
  • LiquidVM - 直接针对硬件
  • azul zing - 商业版,最新垃圾回收的业界标杆,参考zing的垃圾回收产生了ZGC

JDK, JRE, JVM

常用垃圾回收器

阅读更多

JVM - GC和GC Tuning

一、GC的基础知识

什么是垃圾

没有任何引用指向的一个对象或者多个对象(循环引用)

如何定位垃圾

  1. 引用计数(ReferenceCount)
  2. 根可达算法(RootSearching)

常见的垃圾回收算法

  1. 标记清除(mark sweep) - 位置不连续 产生碎片 效率偏低(两遍扫描)
  2. 拷贝算法 (copying) - 没有碎片,浪费空间
  3. 标记压缩(mark compact) - 没有碎片,效率偏低(两遍扫描,指针需要调整)

阅读更多

JVM - JMM内存模型

一、CPU和内存的交互

在计算机中,CPU和内存的交互最为频繁,相比内存,磁盘读写太慢,内存相当于高速的缓冲区。

在多核CPU中,每个处理器都有各自的高速缓存(L1,L2,L3),而主内存确只有一个 。

越靠近CPU的缓存越快也越小。所以L1缓存(一级缓存)很小但很快,并且紧靠着在使用它的CPU内核。L2大一些,也慢一些,并且仍然只能被一个单独的 CPU 核使用。L3在现代多核机器中更普遍,仍然更大,更慢,并且被单个插槽上的所有 CPU 核共享。

当CPU执行运算的时候,它先去L1查找所需的数据,再去L2,然后是L3,最后如果这些缓存中都没有,所需的数据就要去主内存拿。走得越远,运算耗费的时间就越长。

阅读更多

多线程 - Java容器

Java 容器

容器 分两大类Collection、Map,Collection又分三大类List、Set、Queue队列

Set

Set 与 List, Queue 的主要区别是不会有重复元素

ArrayList & LinkedList

  • 没有加锁,线程不安全。
  • ArrayList是基于数组实现的,LinkedList是基于双链表实现的。
  • LinkedList还实现了Deque接口,Deque接口是Queue接口的子接口,它代表一个双向队列,因此LinkedList可以作为双向对列。
  • 因为Array是基于索引(index)的数据结构,它使用索引在数组中搜索和读取数据是很快的,可以直接返回数组中index位置的元素,因此在随机访问集合元素上有较好的性能。Array获取数据的时间复杂度是O(1),但是要插入、删除数据却是开销很大的,因为这需要移动数组中插入位置之后的的所有元素。
  • 相对于ArrayList,LinkedList的随机访问集合元素时性能较差,因为需要在双向列表中找到要index的位置,再返回;但在插入,删除操作是更快的。

阅读更多