当前位置:网站首页>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 .
边栏推荐
- [FPGA]: IP core - multiplier
- 零基础学习CANoe Panel(9)—— 组合框(ComboBox)
- [interview: Basics 03: selection sort]
- Distributed transaction processing scheme big PK!
- MySQL - multi column index
- 38. REM adaptive layout
- Signal processing: < three > DFT and FFT
- Binlog and iptables prevent nmap scanning, xtrabackup full + incremental backup, and the relationship between redlog and binlog
- Princeton chendanqi: how to make the "big model" smaller
- Rtklib source code, RTK difference calculation, rtkpos and replos function process sorting
猜你喜欢

Call bind apply simple summary

cookie sessionStorage localStorage 区别

Zero basic learning canoe panel (7) -- file selection (pathdiaglog)

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

在idea中System.getProperty(“user.dir“)识别到模块(module)路径的方法:Working directory的设置

Distributed transaction processing scheme big PK!

零基础学习CANoe Panel(6)—— 开关/显示控件(Switch/Indicator)
![[about Modelsim simulation] design and Simulation of 4-bit counter](/img/62/f8f7b634684fcffe3bf5f8de073490.png)
[about Modelsim simulation] design and Simulation of 4-bit counter

变频器的四大组成部分和工作原理

【微服务】Eureka+Ribbon实现注册中心与负载均衡
随机推荐
Zero basic learning canoe panel (4) -- button
Princeton chendanqi: how to make the "big model" smaller
SQL optimization skills and precautions
Sentinel three flow control modes
QT create application tray and related functions
新式拥塞控制漫谈
浅析拉格朗日乘数法及其对偶问题
[white hat talks about web security] Chapter 2 browser security
Partition data 2
Dialogue ace phase IV: challenges and opportunities for the future development of distributed databases
二分查找法
Activity review | Anyuan AI X machine heart series lecture No. 1 | deepmind research scientist rohin Shah shares "finding a safe path for AgI"
I admire a Google boss very much, and he left..
[dish of learning notes dog learning C] initial level of structure
神器 ffmpeg —— 操作视频,极度舒适
[FPGA]: IP core ibert
变频器的四大组成部分和工作原理
Five best WordPress advertising plug-ins
在idea中System.getProperty(“user.dir“)识别到模块(module)路径的方法:Working directory的设置
Rtklib source code, RTK difference calculation, rtkpos and replos function process sorting