Cet article a été inclus dansgithubEntrepôt,Cet entrepôt est utilisé pour partagerJavaRésumé des connaissances pertinentes,Y compris:JavaBase、MySQL、Spring Boot、MyBatis、Redis、RabbitMQ、Réseau informatique、Structure des données et algorithmes, etc,Bienvenue.prEtstar!

githubAdresse:https://github.com/Tyson0314/Java-learning

SigithubImpossible d'accéder,AccessiblegiteeEntrepôt.

giteeAdresse:https://gitee.com/tysondai/Java-learning

Catalogue des articles:

Introduction

RabbitMQC'est unerlangFiles d'attente de messages développées.Les files d'attente de messages sont utilisées pour la collaboration asynchrone entre les applications.

Concepts de base

Message:Se compose de l'en - tête et du corps du message.Le corps du message est opaque,L'en - tête du message se compose d'une série d'attributs optionnels,Ces propriétés incluentrouting-key、priority、delivery-mode(Stockage persistant ou non)Attendez..

Publisher:Producteur du message.

Exchange:Recevoir des messages et les acheminer vers un ou plusieursQueue.default exchange Est le commutateur direct par défaut,Le nom est une chaîne vide,Chaque nouvelle file d'attente est automatiquement liée au commutateur par défaut,Le nom de la clé de routage liée est le même que le nom de la file d'attente.

Binding:AdoptionBindingOui.ExchangeEtQueueLiens,Voilà.ExchangePour savoir où acheminer le messageQueueMoyenne.

Queue:Stocker les messages,Les caractéristiques de la file d'attente sont FIFO.Un message peut être distribué à une ou plusieurs files d'attente.

Virtual host:Chaque vhost C'est essentiellement un mini Edition RabbitMQ Serveur,Avoir sa propre file d'attente、Commutateur、Mécanismes de liaison et d'autorisation.vhost - Oui. AMQP La base du concept,Doit être spécifié lors de la connexion,RabbitMQ Par défaut vhost - Oui. / .Lorsque plusieurs utilisateurs différents utilisent le mêmeRabbitMQ serverLorsque le service est fourni,Peut être divisé en plusieursvhost,Chaque utilisateur a son proprevhostCréationexchangeEtqueue.

Broker:Entité du serveur de mise en file d'attente des messages.

Quand utiliserMQ

Pour certaines opérations qui ne nécessitent pas d'effet immédiat,Peut être divisé en,Exécution asynchrone,Mise en œuvre en utilisant la file d'attente des messages.

Prenons l'exemple du système de commande commun,La logique d'entreprise après que l'utilisateur clique sur le bouton de commande peut inclure:Réduction des stocks、Générer les documents correspondants、Envoyer une notification par SMS.Dans ce scénario, on peut utiliser MQ .Envoyer une notification SMS à MQ Exécution asynchrone,Dans le processus de commande(Comme réduire les stocks、Générer les documents correspondants)Envoyez un message à MQ, Laissez le processus principal se terminer rapidement,Et consommés par d'autres filsMQMessage de.

Avantages et inconvénients

Inconvénients:UtilisererlangRéalisation,Défavorable au développement et à l'entretien secondaires;Performances plus élevéeskafkaMauvais,Messages persistants etACKLe débit autonome des messages de production et de consommation est d'environ1-2Environ 10 000.,kafkaLe débit d'une seule machine est de 100 000.

Avantages:Il y a une interface de gestion,Facile à utiliser;Haute fiabilité;Riche en fonctionnalités,Prise en charge de la persistance des messages、Mécanisme de confirmation des messages、Plusieurs mécanismes de distribution de messages.

Exchange Type

ExchangeLa distribution des messages varie selon le type de politique de distribution,Il existe actuellement quatre types de:direct、fanout、topic、headers .headers Le mode est basé surheadersRoutage,En outre headers L'interrupteur et direct L'interrupteur est parfaitement cohérent,Mais les performances sont beaucoup plus faibles.

ExchangeLes règles.

Nom du type Description du type
fanout Envoyez tout àExchangeLe message est acheminé vers tous lesQueueMoyenne
direct Routing Key==Binding Key
topic Correspondance floue
headers ExchangeNe dépend pasrouting keyAvecbinding keyRègles de correspondance pour acheminer les messages,Mais selon le contenu du message envoyéheaderLes propriétés correspondent.

direct

directL'échange achemine les messages versbinding key Et routing keyDans une file d'attente parfaitement appariée.Ça correspond parfaitement、Mode Unicast.

fanout

Tous envoyés à fanout Les messages d'un commutateur de type sont acheminés vers toutes les files d'attente liées à ce commutateur.fanout Le type de message transmis est le plus rapide.

topic

topicUtilisation du commutateurrouting keyEtbinding keyFaire une correspondance floue,Une correspondance réussie envoie le message à la file d'attente appropriée.routing keyEtbinding keyCe sont des points“. ”Chaînes séparées,binding keyIl peut y avoir deux caractères spéciaux“*”Avec“#”,Utilisé pour faire une correspondance floue,Parmi eux“*”Utilisé pour correspondre à un mot,“#”Utilisé pour correspondre à plusieurs mots.

headers

headersLe commutateur est basé sur le contenu du message envoyéheadersPropriété pour le routage.En liaisonQueueAvecExchangeSpécifie un ensemble de paires de valeurs clés;Quand le message est envoyé àExchangeHeure,RabbitMQLe message sera reçuheaders(C'est aussi une forme de paire de valeurs clés),Comparez si les paires de clés correspondent exactementQueueAvecExchangePaire de valeurs clés spécifiée lors de la liaison;Si elle correspond exactement, le message est acheminé versQueue,Sinon, il n'y aura pas de route versQueue.

Message manquant

Scénario de perte de message:Message de production du producteur àRabbitMQ ServerMessage manquant、RabbitMQ ServerMessages stockés manquants etRabbitMQ ServerPerte de message au consommateur.

.La perte de message est résolue de trois façons:Mécanisme de reconnaissance des producteurs、Message de confirmation manuelle du consommateur et persistance.

Mécanisme de reconnaissance des producteurs

Le producteur envoie un message à la file d'attente,Impossible de s'assurer que le message envoyé arrive avec succèsserver.

Solutions:

  1. Mécanisme de transaction.L'expéditeur est bloqué après l'envoi d'un message,Attendez.RabbitMQRéponse de,Avant de continuer à envoyer le message suivant.Mauvais rendement.
  2. Ouverture du mécanisme de confirmation du producteur,Tant que le message est envoyé avec succès au commutateur,RabbitMQEt envoyer unackAux producteurs(Même si le message n'est pasQueueRéception,Sera également envoyéack).Si le message n'est pas envoyé avec succès au commutateur,Il envoie un messagenackMessage,Échec de l'envoi de l'invite.

In Springboot C'est par publisher-confirms Paramètres à définir confirm Mode:

spring:
rabbitmq:
#Ouvert confirm Mécanisme de confirmation
publisher-confirms: true

Fournir une méthode de rappel du côté de la production,Lorsque le serveur a confirmé un ou plusieurs messages,Les producteurs vont revenir sur cette méthode,Traitement ultérieur des messages en fonction des résultats spécifiques,Comme envoyer à nouveau、Journal de bord, etc..

// Le message a - t - il été envoyé avec succès àExchange
final RabbitTemplate.ConfirmCallback confirmCallback = (CorrelationData correlationData, boolean ack, String cause) -> {
log.info("correlationData: " + correlationData);
log.info("ack: " + ack);
if(!ack) {
log.info("Gestion des exceptions....");
}
}; rabbitTemplate.setConfirmCallback(confirmCallback);

Le routage ne peut pas atteindre le message

Le mécanisme de confirmation du producteur garantit seulement que le message arrive correctement au commutateur,Pour le routage du commutateur versQueueMessages échoués,Sera jeté,Perte de message.

Pour les messages non routables,Il y a deux traitements:ReturnMécanisme de messagerie et commutateur de sauvegarde.

ReturnMécanisme de messagerie

ReturnLe mécanisme de message fournit une fonction de rappel ReturnCallback,Lorsque le message est acheminé du commutateur versQueueCe n'est qu'en cas d'échec que cette méthode sera rappelée.Il fautmandatory Set to true ,Pour écouter un message inaccessible.

spring:
rabbitmq:
#DéclencheurReturnCallbackVous devez définirmandatory=true, SinonExchangeJe n'ai pas trouvéQueueEt jeter le message, Sans déclencherReturnCallback
template.mandatory: true

Adoption ReturnCallback Le routage d'écoute ne peut pas atteindre le message.

 final RabbitTemplate.ReturnCallback returnCallback = (Message message, int replyCode, String replyText, String exchange, String routingKey) ->
log.info("return exchange: " + exchange + ", routingKey: "
+ routingKey + ", replyCode: " + replyCode + ", replyText: " + replyText);
rabbitTemplate.setReturnCallback(returnCallback);

Lorsque le message est acheminé du commutateur versQueueEn cas d'échec,Il reviendra. return exchange: , routingKey: MAIL, replyCode: 312, replyText: NO_ROUTE.

Commutateur de secours

Commutateur de secoursalternate-exchange C'est normal.exchange,Quand vous envoyez un message à votre correspondantexchangeHeure,Ça ne correspond pas àqueue,Sera automatiquement transféré au commutateur de sauvegarde correspondant àqueue,Pour que le message ne soit pas perdu.

Confirmation manuelle du message du consommateur

Il est possible que le consommateur n'ait pas eu le temps de traiter le messageMQLe Service s'est arrêté,Perte de message.Parce que le message par défaut est automatiqueack,Une fois que le consommateur aura reçu le messageMQ ServerCe message a été traité,MQ Ce message sera supprimé.

Solutions:Le consommateur est configuré pour reconnaître manuellement le message.Après que le consommateur a traité la logiquebrokerRéponseack,Indique que le message a été consommé avec succès,Peut être obtenu à partir debrokerSupprimer.Quand la consommation de l'informateur a échoué,Voilà.brokerRéponsenack,En fonction de la configuration, décider de rejoindre l'équipe ou de partir debrokerSupprimer,Ou dans la file d'attente des lettres mortes.Tant que le consommateur n'a pas reçu acknowledgment,broker Et ce message sera toujours sauvegardé,Mais non requeue,Et ne sera pas attribué à d'autres Consommateurs.

Configuration manuelle du consommateurack:

#Réglage manuel du consommateur ack
spring.rabbitmq.listener.simple.acknowledge-mode=manual

Traitement du message terminé,Confirmation manuelle:

 @RabbitListener(queues = RabbitMqConfig.MAIL_QUEUE)
public void onMessage(Message message, Channel channel) throws IOException { try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
long deliveryTag = message.getMessageProperties().getDeliveryTag();
//Manuelack;Le deuxième paramètre estmultiple,Set totrue,ReprésentationdeliveryTagAvant le numéro de série(Inclure soi - même)Tous les messages ont été reçus,Set tofalsePour recevoir un message
channel.basicAck(deliveryTag, true);
System.out.println("mail listener receive: " + new String(message.getBody()));
}

Lorsque la consommation de messages échoue,Le consommateur donnebrokerRéponsenack,SiconsumerC'est réglé.requeuePourfalse,EtnackAprèsbrokerSupprimera le message ou entrera dans la file d'attente des lettres mortes,Sinon, le message reviendra dans l'équipe.

Persistance

SiRabbitMQUne exception de service a causé un redémarrage,Le message sera perdu.RabbitMQFournit un mécanisme de persistance,Persister les messages en mémoire sur le disque dur,Même redémarrerRabbitMQ,Le message ne sera pas perdu non plus.

La persistance des messages nécessite les conditions suivantes:

  1. Persistance des paramètres du message.Avant de publier un message,Définir le mode de livraisondelivery modePour2,Indique que le message doit être persistant.
  2. QueueDéfinir la persistance.
  3. Persistance des paramètres de commutation.

Quand un message est envoyé au commutateur,RabbitLe message sera d'abord écrit dans le journal de persistance,Avant d'envoyer la réponse au producteur.Une fois qu'un message a été consommé de la file d'attente et confirmé,RabbitMQCe message sera supprimé du Journal de persistance.Avant le message de consommation,SiRabbitMQSi vous redémarrez,Le serveur reconstruira automatiquement les commutateurs et les files d'attente,Charger les messages du Journal de persistance dans la file d'attente ou le commutateur approprié,Garantie que le message ne sera pas perdu.

File d'attente miroir

QuandMQEn cas de défaillance,Cela peut entraîner l'indisponibilité du service.IntroductionRabbitMQMécanisme de file d'attente miroir pour,Oui.queueMiroir sur d'autres noeuds du cluster.Si un noeud du cluster échoue,Possibilité de passer automatiquement à un autre noeud dans le miroir pour assurer la disponibilité du service.

Habituellement, chaque file d'attente miroir contient unmasterEt plusieursslave,Correspond à différents noeuds.Tous les messages envoyés à la file d'attente miroir sont toujours envoyés directement àmasterEt tous lesslaveAu - dessus de.Sauf quepublishTous les mouvements extérieurs ne font quemasterEnvoyer,Puis parmasterDiffuser les résultats de l'exécution de la commande àslave,L'opération de consommation à partir de la file d'attente miroir est en faitmasterMise en œuvre.

Consommation répétée

Les messages sont répétés pour deux raisons:1.Message répété en production,2.Message répété lors de la consommation.

Le producteur envoie un message àMQ,InMQIl y a eu des fluctuations du réseau au moment de la confirmation,Le producteur n'a pas reçu de confirmation,À ce moment - là, le producteur envoie à nouveau le message,CauseMQUn message en double sera reçu.

Après une consommation réussie,Voilà.MQIl y a eu des fluctuations du réseau au moment de la confirmation,MQAucune confirmation reçue,Pour s'assurer que le message n'est pas perdu,MQIl va continuer à envoyer des messages aux consommateurs avant.Le consommateur reçoit alors deux messages identiques.Parce que les messages dupliqués sont dus à des raisons de réseau,Impossible à éviter.

Solutions:Envoyer des messages avec un message unique à l'échelle mondiale pour chaque messageID,Déterminer si le message a été consommé avant de consommer le message,Garantir l'idémpotence de la logique de consommation du message.Le processus de consommation spécifique est:

  1. Après avoir reçu le message, le consommateur commence paridPour vérifierredis/dbLe message existe - t - il?
  2. S'il n'existe pas,Alors la consommation normale,Écrivez après consommationredis/db
  3. Si elle existe,Pour prouver que le message a été consommé,Jeter directement

Limite de courant côté consommateur

Quand RabbitMQ Quand le serveur a un énorme arriéré de messages,Les messages dans la file d'attente vont inonder les consommateurs,Peut provoquer un crash du serveur client.Dans ce cas, il est nécessaire de limiter le courant du côté consommateur.

Spring RabbitMQ Fournir les paramètres prefetch Vous pouvez définir le nombre de messages traités par une seule requête.Si le message que le consommateur traite simultanément atteint son maximum,Le consommateur bloquera,Ne consomme pas de nouvelles nouvelles,Jusqu'à ce qu'il y ait des nouvelles ack Pour consommer de nouvelles informations.

Ouverture de la limite de courant côté consommateur:

#Nombre de messages traités dans une seule demande,unackNombre maximum de
spring.rabbitmq.listener.simple.prefetch=2

Primitive RabbitMQ Également disponible prefetchSize Et global Deux paramètres.Spring RabbitMQSans ces deux paramètres.

//Limite de taille d'un seul message,0La représentation n'est pas limitée
//global:La fonction limit Current estchannelNiveau ouconsumerNiveau.Lorsque défini àfalse,consumerNiveau,La fonction de limitation du courant est en vigueur,Set totrueSans limitation de courant,Parce quechannelNiveau non atteint.
void basicQos(int prefetchSize, int prefetchCount, boolean global) throws IOException;

File d'attente des lettres mortes

La file d'attente dans laquelle le message de consommation a échoué.

Raison de l'échec de la consommation de messages:

  • Le message a été rejeté et le message n'a pas été repêché(requeue=false)
  • Message timeout not consumed
  • Longueur maximale de la file d'attente atteinte

Configurer la file d'attente des lettres mortes exchange Et queue,Et puis on se lie:

 @Bean
public DirectExchange dlxExchange() {
return new DirectExchange(RabbitMqConfig.DLX_EXCHANGE);
} @Bean
public Queue dlxQueue() {
return new Queue(RabbitMqConfig.DLX_QUEUE, true);
} @Bean
public Binding bindingDeadExchange(Queue dlxQueue, DirectExchange deadExchange) {
return BindingBuilder.bind(dlxQueue).to(deadExchange).with(RabbitMqConfig.DLX_QUEUE);
}

Ajoutez deux paramètres à la file d'attente normale,Lier la file d'attente normale à la file d'attente des lettres mortes.Lorsque la consommation de messages échoue,Les messages sont acheminés vers la file d'attente des lettres mortes.

 @Bean
public Queue sendSmsQueue() {
Map<String,Object> arguments = new HashMap<>(2);
// Lier la file d'attente au commutateur de message privé
arguments.put("x-dead-letter-exchange", RabbitMqConfig.DLX_EXCHANGE);
arguments.put("x-dead-letter-routing-key", RabbitMqConfig.DLX_QUEUE);
return new Queue(RabbitMqConfig.MAIL_QUEUE, true, false, false, arguments);
}

Code complet du producteur:

@Component
@Slf4j
public class MQProducer { @Autowired
RabbitTemplate rabbitTemplate; @Autowired
RandomUtil randomUtil; @Autowired
UserService userService; final RabbitTemplate.ConfirmCallback confirmCallback = (CorrelationData correlationData, boolean ack, String cause) -> {
log.info("correlationData: " + correlationData);
log.info("ack: " + ack);
if(!ack) {
log.info("Gestion des exceptions....");
}
}; final RabbitTemplate.ReturnCallback returnCallback = (Message message, int replyCode, String replyText, String exchange, String routingKey) ->
log.info("return exchange: " + exchange + ", routingKey: "
+ routingKey + ", replyCode: " + replyCode + ", replyText: " + replyText); public void sendMail(String mail) {
//On dirait que les fils ne sont pas sûrs Champ d'application100000 - 999999
Integer random = randomUtil.nextInt(100000, 999999);
Map<String, String> map = new HashMap<>(2);
String code = random.toString();
map.put("mail", mail);
map.put("code", code); MessageProperties mp = new MessageProperties();
//Dans un environnement de production, il n'est pas nécessaire deMessage,Mais utiliser fastJson Attendre que l'outil Convertit l'objet en json Format envoyer
Message msg = new Message("tyson".getBytes(), mp);
msg.getMessageProperties().setExpiration("3000");
//Si le consommateur doit être réglé manuellement ACK ,Alors le côté production envoie le message correlationData ,Et globalement unique,Pour identifier de façon unique le message.
CorrelationData correlationData = new CorrelationData("1234567890"+new Date()); rabbitTemplate.setMandatory(true);
rabbitTemplate.setConfirmCallback(confirmCallback);
rabbitTemplate.setReturnCallback(returnCallback);
rabbitTemplate.convertAndSend(RabbitMqConfig.MAIL_QUEUE, msg, correlationData); //Dépôtredis
userService.updateMailSendState(mail, code, MailConfig.MAIL_STATE_WAIT);
}
}

Code complet du consommateur:

@Slf4j
@Component
public class DeadListener { @RabbitListener(queues = RabbitMqConfig.DLX_QUEUE)
public void onMessage(Message message, Channel channel) throws IOException { try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
long deliveryTag = message.getMessageProperties().getDeliveryTag();
//Manuelack
channel.basicAck(deliveryTag,false);
System.out.println("receive--1: " + new String(message.getBody()));
}
}

Quand il y a des lettres mortes dans la file d'attente normale,RabbitMQ Ce message sera automatiquement republié dans le commutateur de lettre morte défini,Puis il est acheminé vers la file d'attente des lettres mortes.Vous pouvez écouter les messages dans la file d'attente des lettres mortes et les traiter en conséquence.

Autres

pullMode

pullLe mode passe principalement parchannel.basicGetComment obtenir un message,Voici un exemple de code::

GetResponse response = channel.basicGet(QUEUE_NAME, false);
System.out.println(new String(response.getBody()));
channel.basicAck(response.getEnvelope().getDeliveryTag(),false);

Délai d'expiration du message

Un délai d'expiration peut être fixé pour les messages envoyés par le fabricant,En millisecondes(ms)

Message msg = new Message("tyson".getBytes(), mp);
msg.getMessageProperties().setExpiration("3000");

Vous pouvez également spécifier la file d'attente lors de la création de la file d'attentettl,Calculé à partir du message dans la file d'attente,Les messages qui dépassent ce délai seront supprimés.

Liens de référence

RabbitMQBase

SpringbootIntégrationRabbitMQ

RabbitMQPersistance du message

RabbitMQEnvoyer le Code du message

En lignerabbitmqQuestions

Enfin, partagez ungithubEntrepôt,Il y a200Plusieurs livres informatiques classiques,Y compris:CLangues、C++、Java、Python、Front End、Base de données、Système d'exploitation、Réseau informatique、Structure des données et algorithmes、Apprentissage automatique、Programmer la vie, etc,C'est bon.starUn instant.,La prochaine fois que vous cherchez un livre, cherchez directement dessus,Mise à jour continue de l'entrepôt~

githubAdresse:https://github.com/Tyson0314/java-books

SigithubImpossible d'accéder,AccessiblegiteeEntrepôt.

giteeAdresse:https://gitee.com/tysondai/java-books

RabbitMQRésumé des connaissances de base!Autre article Afghanistan

  1. RabbitMQ,ApacheDeActiveMQ,Ali!RocketMQ,Kafka,ZeroMQ,MetaMQ,RedisLa mise en file d'attente des messages est également possible,RabbitMQIntroduction aux scénarios d'application et aux principes de base de,RabbitMQDétails de base,RabbitMQ Bushu

    Mise en file d'attente des messages et introduction à la mise en file d'attente des messages communs 2017-10-10 09:35Système d'exploitation/Client/Reconnaissance faciale Un..File d'attente des messages(MQ)Généralités File d'attente des messages(Message Queue),Est un élément important d'un système distribué,Ses scénarios d'utilisation communs peuvent: ...

  2. RabbitMQConnaissances de base

    RabbitMQConnaissances de base Un..Contexte RabbitMQC'est unerlangDéveloppé parAMQP(Advanced Message Queue )Mise en œuvre open source de.AMQP En fait, l'émergence de la Chine répond aux besoins des masses.,Bien que ...

  3. Tourne.:RabbitMQConnaissances de base

    RabbitMQConnaissances de base Un..Contexte RabbitMQC'est unerlangDéveloppé parAMQP(Advanced Message Queue )Mise en œuvre open source de.AMQP En fait, l'émergence de la Chine répond aux besoins des masses.,Bien que ...

  4. Principes fondamentaux du réseau、ASP.NET Connaissances de base(1)*

    Pourquoi écrire sur Internet? Mon plan était comme ça,Deux jours consécutifs de toilettageASP.NETConnaissances de base développées. En parlant de ça... ,Quelqu'un a demandé..“Ce n'est pas un marchéASP.NET Des notes? ?Pourquoi écrire sur les bases du web? C'est idiot. ?” Voilà pourquoi..Développement en tant que site Web ...

  5. VuexConnaissances de base(2.0)

    Vuex C'est un programme spécial pour Vue.js Modèle de gestion de l'état qui devrait être développé par le programme,C'est similaire à Redux Appliquer à React Dans le projet,Ce sont tous des Flux Architecture.Comparé à Redux,Vuex Plus simple,Réduction des coûts d'apprentissage.L'espoir ...

  6. RabbitMQComment ça marche etRabbitMQConcept de base

    RabbitMQEst un logiciel d'agent de messagerie open source.Elle reçoit les messages des producteurs et les transmet aux consommateurs.C'est comme un intermédiaire,Peut être utilisé pour réduireWebChargement et délai de livraison du serveur d'application. RabbitMQComment fonctionne - t - il? Permettez - moi de vous présenter brièvementR ...

  7. Python Système de connaissances de base en programmation(REF)

    Python Système de connaissances de base en programmation: https://woaielf.github.io/2017/06/13/python3-all/ https://woaielf.github.io/page2/

  8. RabbitMQDétails de base

    Qu'est - ce queMQ? MQNom completMessage Queue, File d'attente des messages(MQ)Est une méthode de communication d'application à application.MQ C'est la consommation. -Un représentant typique du modèle du producteur,Une extrémité écrit continuellement des messages dans la file d'attente des messages,Et l'autre extrémité peut lire dans la file d'attente ...

  9. CookieDétails、ASP.NETConnaissances de base(7)

    ApatridehttpAccord 1.RétrospectivehttpAccord HttpLe Protocole est une réponse à la demande,Il n'y a pas de réponse à une demande,Est apatride,Je ne me souviens pas de la dernière fois et de la page“Que s'est - il passé?”. À propos dehttpCette caractéristique de l'accord,Le lièvre noir est détaillé dans ces trois billets de blog précédents ...

  10. 《MavenSur le terrain》Connaissances de base liées au travail réel

    Je l'ai lu. <MavenSur le terrain>Ce livre,Parce que dans la pratique,Avoir une certaine expérience de son fonctionnement.Donc,,Retournez lire ce livre,Pour saisir plus précisément les connaissances de base à l'intérieur. Je vais vous le présenter à partir de deux points—— 1> m ...

Recommandation aléatoire

  1. iOSDéveloppement——UIArticlesSwiftArticles&amp;UIImageView

    UIImageView override func viewDidLoad() { super.viewDidLoad() titleLabel.text = titleString //Par coordonnées et grand ...

  2. MySQLConfiguration multi - instances

    Environnement expérimental:RHEL6.4Pour minimiser l'installation,mysqlLe paquet d'installation est un paquet d'installation binaire universel,La version estmysql-5.6.26 CréationmysqlUtilisateurs #useradd –M –s /sbin/nologin mysql #y ...

  3. SeniorPHPTechniques d'audit des vulnérabilités des applications

    Préface PHPEst un langage de script largement utilisé,Idéal pourwebDéveloppement.Avec plate - forme croisée,Facile à apprendre,Fonctions puissantes et autres caractéristiques,Selon les statistiques, il y a plus de34% Le site Web de phpRéponse Avec,Y compris:Yahoo.sina.163.sohuEt d'autres grands portails ...

  4. uCOS-IISémaphore et utilisation de

    uCOS-IISémaphore et utilisation de Définition du sémaphore: OS_EVENT* Key1_SEM; OS_EVENT* Key2_SEM; OS_EVENT* Key3_SEM; Création de sémaphores: Key1_SEM= ...

  5. Comment faireLinux Pour obtenir une partition de disque dur ou un système de fichiersUUID?

    En tant que Linux Administrateur système,Vous devriez savoir comment vérifier la partition UUID Ou du système de fichiers UUID.Parce que la plupart Linux Tous les systèmes sont utilisés UUID Monter la partition.Vous pouvez /etc/fstab Le fichier peut ...

  6. (6.2)vimÉditeur de texte

    vi / vim- Oui.Unix / LinuxL'éditeur de texte le plus couramment utilisé et très puissant. vimL'éditeur de texte n'a que des commandes, Pas de menu .

  7. spring mvc 500ErreurAllocate exception for servlet AppService javax.naming.NamingException: Cannot create resource instance C'est vrai.@ResourceRaisons

    Les premiers jours ont été testés,Ce problème s'est produit avec un autre répertoire Grave: Allocate exception for servlet AppService javax.naming.NamingException: ...

  8. CentOS 7Installation supérieurePure-FTPd

    # Installation yum install epel-release yum install pure-ftpd Le fichier de localisation est situé à/etc/pure-ftpd/pure-ftpd.conf # Modifier le profil # Note: ...

  9. Le plus simpleXMLUtilisation

    Lors de la transmission des données,XMLEtJSONEst le format de données le plus couramment utilisé,SQL ServerPrise en charge depuis les premières versionsXMLFormat,Et pourJSONFormat,SQL ServerDe2016Prise en charge du démarrage de la version.La plupart des systèmes de base de données n'ont pas été mis à jour versSQ ...

  10. ubuntuModifier la résolution en dessous

      Installé dans la machine virtuelleubuntuMais non.1600*900Résolution de Première étape: xrandr -q .Voir toutes les résolutions dans le système actuel Deuxième étape: cvt 1600 900 Obtenir les données de résolution de changement requises Troisième étape:  ww ...