当前位置:网站首页>Redismission inventory deduction demo
Redismission inventory deduction demo
2022-07-24 10:58:00 【dotaer-df】
In a distributed scenario , To realize the lock, if only through Synchronized Keywords don't work , because Synchronized It's just here java Locked in the process . To implement distributed locks, you can use redission. In this paper nginx Reverse proxy +redission Realize inventory deduction demo.
Introduce dependencies
<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(" Successful sale , The remaining :"+ realStock);
return "success";
}else{
System.out.println(" The surplus stock is insufficient ");
return "fail";
}
} finally {
lock.unlock();
}
}
}operation redis There are many kinds of clients (jedis,lettuce,redission contrast ), Officially recommended java Client such as jedis,springboot2.0 Default adopted lettuce, as well as redission, Here we directly adopt redission. And use redission It should be noted that bucket Concept ,RBucket Object is a general object bucket, which can be used to store any type of object , Its bottom layer is by default FstCodec Serialize storage , Because you need to go in advance redis Input inside 50 stock , If direct set shopKey 50 , When calling redissonClient.getBucket(key), The following exceptions will occur , Because the types before and after serialization are inconsistent .
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)
There are two solutions
1. One is to insert the serialized result directly So called redissonClient.getBucket(key) The deserialization type is also consistent
set shopKey "\xfc\x0250"
2. One is to set bucket Serialization mode and then set
redissonClient.getBucket(key, new StringCodec());
set shopKey 50
nginx To configure Most of them can be configured by default , The changes that need to be made have been approved # // Mark it out , After configuration, use the configuration file to start it .
Start command -c Indicates that the following configuration file is used when starting , It can also be used before startup -t Command to test whether the configuration is successful , If the configuration is successful xx.conf test is successful, And then it starts .
/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;
# // Achieve a load balancing 8081,8082 Ports are accessed in turn
upstream redisLock{
server 10.254.2.27:8081 weight=1; #ipV4, adopt ipconfig Command view
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;
# // Forward to the configured 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/*;
}
then idea To start, respectively, 8081,8082 Two ports , And then visit http://127.0.0.1/getLock that will do , Here you can use jmeter and postman Simulate concurrent requests .
边栏推荐
- 零基础学习CANoe Panel(5)——改变变量的值,控件图像也改变,这是怎么回事?
- Detailed explanation of the implementation process of redistribution watchdog
- cookie sessionStorage localStorage 区别
- 5个最佳WordPress广告插件
- Openresty Lua resty logger socket log transfer
- [dish of learning notes, dog learning C] minesweeping game
- Cookie sessionstorage localstorage differences
- Binlog and iptables prevent nmap scanning, xtrabackup full + incremental backup, and the relationship between redlog and binlog
- LoRa无线技术与LoRaWAN网关模块的区别
- Zero basic learning canoe panel (9) -- combobox
猜你喜欢

Flink 运行架构详解

Zero basic learning canoe panel (8) -- hex/text editor

Zero basic learning canoe panel (10) -- checkbox

Zero basic learning canoe panel (7) -- input/output box
![[FPGA]: use of MicroBlaze](/img/f4/5114bf4bde10adaa22c7441350575c.png)
[FPGA]: use of MicroBlaze
![[live registration] analysis of location cache module and detailed explanation of OCP monitoring and alarm](/img/d8/a367c26b51d9dbaf53bf4fe2a13917.png)
[live registration] analysis of location cache module and detailed explanation of OCP monitoring and alarm

【类、抽象与继承】

2018 arXiv | Objective-Reinforced Generative Adversarial Networks (ORGAN) for Sequence Generation Mo

MySQL - normal index

Cub school learning - Kernel Development
随机推荐
小熊派学习——内核开发
BBR and queuing
MySQL - unique index
Tidb query SQL report runtime error: index out of range [-1] error
Cub school learning - Kernel Development
Zero basic learning canoe panel (8) -- hex/text editor
Cross platform audio playback Library
MySQL - update data records in tables
Partition data 2
[white hat talks about web security] Chapter 2 browser security
cookie sessionStorage localStorage 区别
App automation and simple environment construction
[interview: Basics 02: bubble sort]
[ISE] development process plus bit, burning of MCS files
零基础学习CANoe Panel(10)—— 复选框(CheckBox)
轻松读懂三极管,原来它是这样工作的
西门子200smart自创库与说明
PC Museum (1) 1970 datapoint 2000
数组元素移除问题
js树形结构,根据里层id找出它所属的每层父级集合