接下来我们利用代码的形式验证一下zk的分布式锁,在这里我们需要用到JMeter、nginx还有SpringBoot,接下来我们来实现一下看效果。
1、JMeter
1、我们随意在网上下载一个JMeter的版本,我这里瞎咋的是5.2.1版本的,解压之后,我们打开bin目录,里面有一个jmeter.bat文件,我们鼠标双击它,如下图所示:
2、稍等一会,出现如下界面,我们需要需要先添加一个线程组,代表我们需要一次性发送多少个请求,如下图所示:
一个请求就是一个线程,这里我们设置在一秒钟发送10个请求,也就相当于是10个用户同时请求,如下图所示:
3、但是现在还不知道请求哪个系统去做什么事情,我们需要去添加一个http的请求,如下图所示:
添加完成之后,我们需要设置一些http请求的参数,,比如端口号、地址等等,如下图所示,我们这里直接请求的是nginx,所以参数如下:
4、接下来我们添加一个listener,有了这个我们就可以看到每一次请求的请求头数据以及响应数据,如下图所示:
到这里,JMeter就已经配置好了,就先放在这
2、nginx
1、下载nginx,这里我下载的是1.17.9版本
下载好之后我们来解压,解压完成之后打开是一个如下图所示的界面:
我们打开conf文件夹下的nginx.conf文件,修改成下面代码的样子:
也可以不用全部替换,配置文件下面我会明确说一下我改了什么地方
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream app{
server localhost:8080;
server localhost:8081;
}
server {
listen 9000;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
proxy_pass http://app/;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
2、首先我们在server节点上面添加一个 upstream 模块,起名叫 app ,这个名字可以自定义,如下图所示:
upstream app{
server localhost:8080;
server localhost:8081;
}
3、接着我们在 server 节点里面有一个 location 属性下加上一个http代理,代理上面配置的 upstream 模块,如下图所示:
proxy_pass http://app/;
由于我们的 upstream 模块没有配置其它东西,所以现在 nginx 就会轮询去调用里面配置的两个接口,8080和8081
4、启动:配置在上面已经完成,接下来就剩启动 nginx 了,在如下界面打开cmd
打开cmd窗口后如下图所示,输入start nginx -c conf/nginx.conf,回车,如果没有报错,则表示nginx启动成功。
5、判断nginx是否启动成功,
首先这里nginx向外提供的端口号我修改了,因为我的电脑上80端口已经被别的进程占用了,如下图所示:
浏览器中输入如下地址:
http://localhost:9000/
如果浏览器中显示下图界面,则代表启动成功:
3、SpringBoot代码
代码链接
提取码:j4zy
代码可根据上面的链接去获取
然后我们顺序启动两个服务,一个8080,一个8081,如下图所示:
4、设计数据库
数据库设置两张表,两张表的脚本如下:
--order表
DROP TABLE IF EXISTS `order`;
CREATE TABLE `order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pid` int(11) DEFAULT NULL,
`user_id` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1513 DEFAULT CHARSET=utf8mb4;
--product表
DROP TABLE IF EXISTS `product`;
CREATE TABLE `product` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`product_name` varchar(255) DEFAULT NULL,
`stock` int(11) DEFAULT NULL,
`version` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
INSERT INTO `product` VALUES ('1', '哈哈大礼包', '5', '0');
执行完成之后的表数据如下图所示:
5、不加锁测试
我们现在库存里面只有5个库存,但是有10个用户过来请求,本应该是不够的,但是现在没有添加分布式锁,在高并发的情况下应该是每个用户都可以抢到的,所以直接导致库存为负数,这样显然是不正确的,具体测试如下:
1、直接点击下图中的开始按钮,选择日志不保存,如下图所示:
2、我们会发现监听的10个请求全部获取成功了,这样肯定是有问题的,如下图所示:
3、接下来我们再看看数据库,发现数据库的库存已经成为了负数。
订单表生成了10个订单:
6、加锁测试
1、在上面的代码基础上我们加上锁,如下图所示,修改两个类:
TestController
CuratorCfg
2、再次重新启动两个服务,8080,8081
并将数据库的数据改为原来的样子。
3、再次和依照上面的方式启动JMeter,观察效果,这次只有五个成功,如下图所示:
4、接下来我们看一下数据库:
数据正确,分布式锁已经加成功。