当前位置:网站首页>Pool de connexion redis personnalisé
Pool de connexion redis personnalisé
2022-07-02 09:20:00 【Niceyz】
Un entretien d'usine:Examiner la conception du service et certaines exigences en matière d'interface.

Interface 2 résoudre le problème,Exigence 1 Limitation du courant; Exigence II Interface idempotent;Exigence 3 Paramètres de temporisation de la programmation réseau;Exigence 4 Limitation du courant;
Exigence 5 RésolutionHttpClientProblèmes de sécurité des fils,Idées personnaliséesHttpClientPool de connexion.
Mauvaise écriture:Dans un scénario simultané,Allez, viens.1000Demandes secondaires,Établissement1000Connexions secondaires,Les frais généraux de connexion sont mortels.

Nous utilisonssocketDéfinir unhttpclient,Montre - moi.socketThread Unsafe Phenomenon:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* Description: SocketLe réseau est connecté àredis,À utiliserredisProtocole de connexion
* Author: yz
* Date: Created in 2021/1/6 11:14
*/
public class Connetion {
private String host;
private int post;
private Socket socket; // Thread Unsafe
private InputStream inputStream;
private OutputStream outputStream;
public Connetion(String host, int post) {
this.host = host;
this.post = post;
}
/**
* Déterminer si la connexion a été établie , Déterminer si la connexion est initialisée , Ou la connexion n'est pas déconnectée
*/
public boolean isConnection(){
if(socket !=null && inputStream !=null && socket.isClosed()){
return true;
}
try {
socket = new Socket(host,post);
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* Envoyer une commande
*/
public String sendCommand(byte[] command){
if(isConnection()){
try {
// Le client écrit d'abord les données
outputStream.write(command);
// Lire la réponse du serveur
byte[] res = new byte[1024];
int length = 0;
while ((length=inputStream.read(res))>0){
return new String(res,0,length);
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}/**
* Description: redisClasse d'outils de protocole
* Author: yz
* Date: Created in 2021/1/6 11:41
*/
public class RedisProtocolUtils {
public static final String DOLIER = "$";
public static final String ALLERTSTIC = "*";
public static final String CRLE = "\r\n";
public static byte[] buildRespByte(Command command,byte[]... bytes){
StringBuilder sb = new StringBuilder();
sb.append(ALLERTSTIC).append(bytes.length+1).append(CRLE);
sb.append(DOLIER).append(command.name().length()).append(CRLE);
sb.append(command.name()).append(CRLE);
for (byte[] arg : bytes) {
sb.append(DOLIER).append(arg.length).append(CRLE);
sb.append(new String(arg)).append(CRLE);
}
return sb.toString().getBytes();
}
/**
* redis set,getLes ordres
*/
public enum Command{
SET,GET
}
}/**
* Description:
* Author: yz
* Date: Created in 2021/1/6 15:01
*/
public class ClientRunalbe implements Runnable {
private BatRedisClient client;
private String value;
public ClientRunalbe(BatRedisClient client, String value) {
this.client = client;
this.value = value;
}
@Override
public void run() {
client.set("ant",value);
}
}import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Description: redis Le client de connexion contient redisAccord etsocket
* Author: yz
* Date: Created in 2021/1/6 11:53
*/
public class BatRedisClient {
private Connetion connetion;
public BatRedisClient(String host,int port){
connetion = new Connetion(host,port);
}
public String set(String key,String value){
String result = connetion.sendCommand(
RedisProtocolUtils.buildRespByte(RedisProtocolUtils.Command.SET,key.getBytes(),value.getBytes()));
System.out.println("Thread name:"+Thread.currentThread().getName()
+"[result]:"+result.replace("\r\n","")+"[value]:"+value);
return result;
}
public String get(String key){
String result = connetion.sendCommand(
RedisProtocolUtils.buildRespByte(RedisProtocolUtils.Command.GET,key.getBytes(),key.getBytes()));
return result;
}
public static void main(String[] args) {
BatRedisClient client = new BatRedisClient("localhost",6379);
ExecutorService pool = Executors.newCachedThreadPool();
for (int i = 0; i < 20; i++) {
// Il y a un phénomène : Le thread actuel lit à redis Données de réponse retournées à d'autres Threads
pool.execute(new ClientRunalbe(client,"123"+i));
}
}
}Mise en œuvremianTest de méthode,20Exécution simultanée des threads,Les résultats sont les suivants::1,Non exécuté20Une fois,2,redis Les résultats retournés ont été collés ensemble , En fait, une demande obtient le résultat d'une autre demande

1,Non exécuté20Une fois: Plusieurs Threads partagent un socket, Quand un fil écrit à moitié ,cpu Il n'y avait plus de créneaux horaires au moment de l'expédition , Le deuxième thread obtient cupFilm temporel, Les données sont également écrites , Ces données qui n'ont pas été écrites seront également redisLire à, Mais ne peut pas être analysé ,redisImpossible de retourner la réponse, Thread read not responding ,EntréeioBlocage.

2,redis Les résultats retournés ont été collés ensemble : La quantité de données est faible au moment de l'envoi , Le paquet envoyé par le thread est complet ,Voilà.redis Après cela, il peut être résolu en deux requêtes , C'est aussi le retour normal des données ,Si le fil1ObtenircupDroit d'utilisation,InreadLors de la lecture des données, Peut lire toutes les données du tampon en même temps , Après analyse, on a trouvé que +OK+OKC'est la forme.

Résoudre avec un pool de Threads personnalisé socket Problème de sécurité multithreadé ,Prends ça.clientObjet placé surpoolDans la piscine

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque; // File d'attente bidirectionnelle
import java.util.concurrent.LinkedBlockingQueue; // File d'attente unidirectionnelle
/**
* Description: redisPool de connexion
* Author: yz
* Date: Created in 2021/1/6 15:19
*/
public class RedisClientPool {
private List<BatRedisClient> allObject;
private LinkedBlockingQueue<BatRedisClient> linkedBlockingQueue;
public RedisClientPool(String host,int port,int connectionCount){
allObject = new ArrayList<>();
this.linkedBlockingQueue = new LinkedBlockingQueue<>(10);
for (int i = 0; i < connectionCount; i++) {
BatRedisClient client = new BatRedisClient(host,port);
linkedBlockingQueue.add(client);
allObject.add(client);
}
}
/**
* AccèsclientConnexion
*/
public BatRedisClient getClient(){
try {
return linkedBlockingQueue.take(); // or poll
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
/**
* Oui.clientRetour au pool de connexion
*/
public void returnClient(BatRedisClient client){
if(client == null){
return;
}
if(!allObject.contains(client)){
throw new IllegalStateException(
"Returned object not currently part of this pool");
}
try {
linkedBlockingQueue.put(client);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}/**
* Description: Utiliser la personnalisationredisPool de connexion
* Author: yz
* Date: Created in 2021/1/6 15:28
*/
public class ClientPoolRunable implements Runnable {
private RedisClientPool pool;
private String value;
public ClientPoolRunable(RedisClientPool pool, String value) {
this.pool = pool;
this.value = value;
}
@Override
public void run() {
BatRedisClient client = pool.getClient();
client.set("ant",value);
pool.returnClient(client);
}
}import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Description: TestsredisPool de connexion
* Author: yz
* Date: Created in 2021/1/6 15:30
*/
public class Main {
public static void main(String[] args) {
ExecutorService pool = Executors.newCachedThreadPool();
RedisClientPool redisClientPool = new RedisClientPool("localhost",6379,10);
for (int i = 0; i < 20; i++) {
pool.execute(new ClientPoolRunable(redisClientPool,"123"+i));
}
}
}Mise en œuvremainTest de méthode,Les résultats sont les suivants:, Exactement. 20Une fois,Il n'est plus là.+OK+OKC'est un phénomène.

Élargir les connaissances:File d'attente

边栏推荐
- [go practical basis] gin efficient artifact, how to bind parameters to structures
- 京东高级工程师开发十年,编写出:“亿级流量网站架构核心技术”
- Don't look for it. All the necessary plug-ins for Chrome browser are here
- 「面试高频题」难度大 1.5/5,经典「前缀和 + 二分」运用题
- Oracle modify database character set
- AMQ6126问题解决思路
- Gocv split color channel
- Webflux responsive programming
- Microservice practice | fuse hytrix initial experience
- Machine learning practice: is Mermaid a love movie or an action movie? KNN announces the answer
猜你喜欢

Chrome浏览器标签管理插件–OneTab

DTM distributed transaction manager PHP collaboration client V0.1 beta release!!!

破茧|一文说透什么是真正的云原生

There is a problem with MySQL installation (the service already exists)

Programmers with ten years of development experience tell you, what core competitiveness do you lack?

西瓜书--第五章.神经网络

微服务实战|手把手教你开发负载均衡组件

队列管理器running状态下无法查看通道

京东面试官问:LEFT JOIN关联表中用ON还是WHERE跟条件有什么区别

C4D quick start tutorial - C4d mapping
随机推荐
定时线程池实现请求合并
查看was发布的应用程序的端口
【Go实战基础】gin 如何验证请求参数
ORA-12514问题解决方法
[go practical basis] gin efficient artifact, how to bind parameters to structures
Cloudrev self built cloud disk practice, I said that no one can limit my capacity and speed
Taking the upgrade of ByteDance internal data catalog architecture as an example, talk about the performance optimization of business system
Number structure (C language -- code with comments) -- Chapter 2, linear table (updated version)
How to realize asynchronous programming in a synchronous way?
以字节跳动内部 Data Catalog 架构升级为例聊业务系统的性能优化
Complete solution of servlet: inheritance relationship, life cycle, container, request forwarding and redirection, etc
[staff] time sign and note duration (full note | half note | quarter note | eighth note | sixteenth note | thirty second note)
「Redis源码系列」关于源码阅读的学习与思考
Microservice practice | teach you to develop load balancing components hand in hand
Gocv boundary fill
Double non undergraduate students enter the factory, while I am still quietly climbing trees at the bottom (Part 1)
Knife4j 2.X版本文件上传无选择文件控件问题解决
盘点典型错误之TypeError: X() got multiple values for argument ‘Y‘
机器学习之数据类型案例——基于朴素贝叶斯法,用数据辩男女
Chrome user script manager tempermonkey monkey