当前位置:网站首页>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

边栏推荐
- Watermelon book -- Chapter 5 neural network
- 微服务实战|Eureka注册中心及集群搭建
- Chrome video download Plug-in – video downloader for Chrome
- Machine learning practice: is Mermaid a love movie or an action movie? KNN announces the answer
- Flink - use the streaming batch API to count the number of words
- C language - Blue Bridge Cup - 7 segment code
- win10使用docker拉取redis镜像报错read-only file system: unknown
- Pdf document of distributed service architecture: principle + Design + practice, (collect and see again)
- Ora-12514 problem solving method
- Microservice practice | declarative service invocation openfeign practice
猜你喜欢

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

In depth analysis of how the JVM executes Hello World

Data type case of machine learning -- using data to distinguish men and women based on Naive Bayesian method

What is the future value of fluorite mine of karaqin Xinbao Mining Co., Ltd. under zhongang mining?
![[go practical basis] how to install and use gin](/img/0d/3e899bf69abf4e8cb7e6a0afa075a9.png)
[go practical basis] how to install and use gin

Ora-12514 problem solving method

十年开发经验的程序员告诉你,你还缺少哪些核心竞争力?

Microservice practice | fuse hytrix initial experience
![[staff] time mark and note duration (staff time mark | full note rest | half note rest | quarter note rest | eighth note rest | sixteenth note rest | thirty second note rest)](/img/7f/2cd789339237b7a881bfed7b7545a9.jpg)
[staff] time mark and note duration (staff time mark | full note rest | half note rest | quarter note rest | eighth note rest | sixteenth note rest | thirty second note rest)

数构(C语言)——第四章、矩阵的压缩存储(下)
随机推荐
盘点典型错误之TypeError: X() got multiple values for argument ‘Y‘
别找了,Chrome浏览器必装插件都在这了
C language implementation of mine sweeping game
Cartoon rendering - average normal stroke
Sentinel reports failed to fetch metric connection timeout and connection rejection
hystrix 实现请求合并
微服务实战|微服务网关Zuul入门与实战
How to realize asynchronous programming in a synchronous way?
Redis sorted set data type API and application scenario analysis
企业级SaaS CRM实现
A detailed explanation takes you to reproduce the statistical learning method again -- Chapter 2, perceptron model
Taking the upgrade of ByteDance internal data catalog architecture as an example, talk about the performance optimization of business system
[go practical basis] gin efficient artifact, how to bind parameters to structures
使用IBM MQ远程连接时报错AMQ 4043解决思路
gocv opencv exit status 3221225785
聊聊消息队列高性能的秘密——零拷贝技术
Microservice practice | teach you to develop load balancing components hand in hand
京东面试官问:LEFT JOIN关联表中用ON还是WHERE跟条件有什么区别
【Go实战基础】gin 如何验证请求参数
Oracle modify database character set