当前位置:网站首页>redission扣库存demo
redission扣库存demo
2022-07-22 10:32:00 【dotaer-df】
在分布式场景中,要实现锁如果仅仅通过Synchronized关键字是不行的,因为Synchronized只是在此java进程中进行了上锁。要想实现分布式锁即可采用redission。本文采用nginx反向代理+redission实现扣库存demo。
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.10.6</version>
</dependency>
@Configuration
public class RedisConfig {
@Bean
public RedissonClient getRedisClient() {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379").setPassword("123456");
return Redisson.create(config);
}
}
@RestController
public class RedissionController {
@Autowired
RedissonClient redissonClient;
@GetMapping(value = "/getLock")
public String getLock() {
String lockKey = "lock";
String key = "shopKey";
RLock lock = redissonClient.getLock(lockKey);
try {
lock.lock();
RBucket<String> bucket = redissonClient.getBucket(key);
int stock = Integer.parseInt(bucket.get());
if (stock > 0) {
int realStock = stock - 1;
bucket.set(String.valueOf(realStock));
System.out.println("出售成功,剩余:"+ realStock);
return "success";
}else{
System.out.println("剩余库存不足");
return "fail";
}
} finally {
lock.unlock();
}
}
}
操作redis客户端有许多种(jedis,lettuce,redission对比),官方推荐的java客户端如jedis,springboot2.0默认采用的lettuce,以及redission,这里就直接采用redission。而采用redission需要注意的是bucket概念,RBucket对象是一种通用对象桶可以用来存放任类型的对象,它底层是默认采用 FstCodec进行序列化存储,因为需要提前往redis里面录入50库存,如果直接set shopKey 50 ,当调用redissonClient.getBucket(key),会出下面的异常,因为序列化前后的类型不一致。
2019-05-15 13:39:59.973 [redisson-netty-2-3] ERROR o.r.c.h.CommandDecoder [decodeCommand:203] - Unable to decode data. channel: [id: 0x477c5ced, L:/192.168.4.94:57423 - R:10.10.10.43/10.10.10.43:6379], reply: ReplayingDecoderByteBuf(ridx=102, widx=102), command: (GET), params: [Geek:xxxxx:xxxx]
java.io.IOException: java.lang.NullPointerException
at org.nustaq.serialization.FSTObjectInput.readObject(FSTObjectInput.java:247)
at org.redisson.codec.FstCodec$1.decode(FstCodec.java:228)
at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:368)
at org.redisson.client.handler.CommandDecoder.decodeCommand(CommandDecoder.java:200)
at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:140)
at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:115)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:502)
at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:278)
有两种解决方式
1.一种是直接插入序列化后的结果 那么调用redissonClient.getBucket(key)反序列化类型也是一致的
set shopKey "\xfc\x0250"
2.一种是设置bucket序列化方式然后进行set
redissonClient.getBucket(key, new StringCodec());
set shopKey 50
nginx配置 大部分采用默认配置即可,需要修改的地方已经通过 # //标示出来,配置完成后使用该配置文件启动一下即可。
启动命令 -c 表示启动时使用下面的配置文件,也可以在启动前采用-t命令测试是否配置成功,如果配置成功会显示xx.conf test is successful,然后再启动。
/usr/local/Cellar/nginx/1.21.1/bin/nginx -c /usr/local/Cellar/nginx/1.21.1/.bottle/etc/nginx/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;
# // 实现一个负载均衡 8081,8082端口依次访问
upstream redisLock{
server 10.254.2.27:8081 weight=1; #ipV4,通过ipconfig命令查看
server 10.254.2.27:8082 weight=1;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
# // 转发到上面配置的upstream
proxy_pass http://redisLock;
}
#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;
# }
#}
include servers/*;
}
然后idea分别启动8081,8082两个端口,然后访问http://127.0.0.1/getLock即可,这里可以使用jmeter和postman模拟并发请求。
边栏推荐
- LeetCode206——反转链表
- win8.1系统发生蓝屏问题解决方法、IE主页被恶意劫持怎么解决?
- How to deal with DNS hijacked? Five ways to deal with it
- Introduction to machine learning: linear regression-1
- 《因果学习周刊》第10期:ICLR2022中最新Causal Discovery相关论文介绍
- 她力量系列六丨杨笛一:女孩长大后数理化可以很好,科研可以很鲜活
- On the horizontal trigger and edge trigger of epoll
- When using CV2 to realize face recognition, Chinese is displayed on the recognition frame
- Core concepts of elastic search learning Introduction (4)
- LeetCode53——Maximum Subarray——3 different methods
猜你喜欢
知名软件ADSafe暗藏恶意代码 从众多网站劫持流量
Leetcode206 - reverse linked list
DNS劫持如何预防、DNS是什么?DNS劫持详解
信号量实现同步互斥经典案例
LeetCode146——LRU Cache——DS Design
canny边缘检测
What are the ways for Baidu homepage to be hijacked by TN? There are two ways to solve Baidu hijacking
Kubernetes基础入门
她力量系列六丨杨笛一:女孩长大后数理化可以很好,科研可以很鲜活
Websites jump inexplicably. What is website hijacking from Baidu? How to solve Baidu snapshot hijacking
随机推荐
[summary and reflection] seven core principles of high availability architecture design
How to repair DNS hijacking perfectly? How to solve DNS hijacking and how to repair it perfectly
网站莫名跳转,从百度谈什么是网站劫持?百度快照劫持怎么解决
Leetcode206 - reverse linked list
RP file Chrome browser view plug-in
Elastic Search 学习入门之中文检索(八)
How to deal with DNS hijacking, DNS hijacking, and DNS hijacking solutions
LeetCode53——Maximum Subarray——3 different methods
浅谈epoll的水平触发与边沿触发
Generate an external inspection script to delete all tables in the database
mysql查询blob
What is the meaning of DNS hijacking, the principle of DNS hijacking and several solutions
dns被劫持有什么现象?DNS是什么 dns被劫持了如何解决
LeetCode912——sort an array—— quick sort algorithm
网站莫名跳转,从百度谈什么是网站劫持?DNS劫持(域名劫持)DNS劫持是啥
Elastic Search 学习入门之ES的简单操作命令(二)
Introduction to machine learning: linear regression-1
Leetcode 32. longest valid bracket
Kubernets原理分解
vim 使用tips