Java implémente plusieurs algorithmes d'équilibrage de charge
Tout d'abord, permettez-moi de vous présenter ce qu'est l'équilibrage de charge (extrait de l'encyclopédie)
L'équilibrage de charge est construit sur structure de réseau existante, il fournit une méthode peu coûteuse, efficace et transparente pour étendre la bande passante des périphériques et des serveurs réseau, augmenter le débit, améliorer les capacités de traitement des données du réseau et améliorer la flexibilité et la disponibilité du réseau.
Équilibrage de charge, le nom anglais est Load Balance, ce qui signifie allouer l'exécution à plusieurs unités opérationnelles, telles que les serveurs Web, les serveurs FTP, les serveurs d'applications de clé d'entreprise et autres serveurs critiques, etc., afin que pour terminer le travail ensemble Tâche.
Cet article parle de divers algorithmes pour "répartir uniformément les requêtes envoyées de l'extérieur à un certain serveur dans une structure symétrique", et démontre l'implémentation spécifique de chaque algorithme dans le code Java. OK, ci-dessous Passons au. Avant d'entrer dans le sujet, écrivez d'abord une classe pour simuler la liste IP :
import java.util.HashMap; /** * @author [email protected] * @date 二月 07, 2017 */ public class IpMap { // 待路由的Ip列表,Key代表Ip,Value代表该Ip的权重 public static HashMap<String, Integer> serverWeightMap = new HashMap<String, Integer>(); static { serverWeightMap.put("192.168.1.100", 1); serverWeightMap.put("192.168.1.101", 1); // 权重为4 serverWeightMap.put("192.168.1.102", 4); serverWeightMap.put("192.168.1.103", 1); serverWeightMap.put("192.168.1.104", 1); // 权重为3 serverWeightMap.put("192.168.1.105", 3); serverWeightMap.put("192.168.1.106", 1); // 权重为2 serverWeightMap.put("192.168.1.107", 2); serverWeightMap.put("192.168.1.108", 1); serverWeightMap.put("192.168.1.109", 1); serverWeightMap.put("192.168.1.110", 1); } }
Méthode Round Robin
Le principe de l'algorithme de planification round robin est d'envoyer des données depuis l'utilisateur. les requêtes sont attribuées tour à tour aux serveurs internes, en commençant de 1 jusqu'à N (le nombre de serveurs internes), puis le cycle recommence. L'avantage de l'algorithme est sa simplicité. Il n'est pas nécessaire d'enregistrer l'état de toutes les connexions en cours, il s'agit donc d'une planification sans état.
L'implémentation du code est à peu près la suivante :
import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * @author [email protected] * @date 二月 07, 2017 */ class RoundRobin { private static Integer pos = 0; public static String getServer() { // 重建一个Map,避免服务器的上下线导致的并发问题 Map<String, Integer> serverMap = new HashMap<String, Integer>(); serverMap.putAll(IpMap.serverWeightMap); // 取得Ip地址List Set keySet = serverMap.keySet(); ArrayList keyList = new ArrayList(); keyList.addAll(keySet); String server = null; synchronized (pos) { if (pos > keySet.size()) pos = 0; server = keyList.get(pos); pos ++; } return server; } }
Étant donné que la liste d'adresses dans serverWeightMap est dynamique, les machines peuvent se mettre en ligne, se déconnecter ou être en panne à tout moment, donc dans l'ordre pour éviter une éventuelle concurrence Le problème est qu'une nouvelle variable serverMap doit être créée à l'intérieur de la méthode. Copiez maintenant le contenu de serverMap dans le thread local pour éviter d'être modifié par plusieurs threads. Cela peut introduire de nouveaux problèmes. Les modifications apportées à serverWeightMap après la réplication ne peuvent pas être répercutées sur serverMap. Autrement dit, lors de ce cycle de sélection de serveur, l'algorithme d'équilibrage de charge ne sera pas en mesure de savoir si de nouveaux serveurs ou des serveurs hors ligne sont ajoutés. Peu importe si vous en ajoutez un nouveau. Si un serveur se déconnecte ou tombe en panne, vous pouvez accéder à une adresse inexistante. Par conséquent, l'appelant du service doit disposer d'un traitement de tolérance aux pannes correspondant, tel que la réinitialisation de la sélection et de l'appel du serveur.
Pour la variable de position pos actuellement interrogée, afin de garantir l'ordre de sélection du serveur, elle doit être verrouillée pendant le fonctionnement, afin qu'un seul thread puisse modifier la valeur de pos en même temps, sinon lorsque la variable pos Si elle est modifiée simultanément, l'ordre de sélection du serveur ne peut pas être garanti, et cela peut même faire sortir le tableau keyList des limites.
L'avantage de la méthode d'interrogation est qu'elle tente d'atteindre un équilibre absolu dans le transfert des demandes.
L'inconvénient de la méthode d'interrogation est que pour atteindre l'équilibre absolu du transfert des demandes, un prix considérable doit être payé, car afin d'assurer l'exclusion mutuelle des modifications de variables pos, un verrou pessimiste lourd synchronisé doit être introduit. Cela entraînera une baisse significative du débit simultané de ce code d'interrogation.
Méthode aléatoire (aléatoire)
Grâce à l'algorithme aléatoire du système, l'un des serveurs est sélectionné au hasard pour l'accès en fonction de la valeur de taille de liste du serveur principal. On peut savoir d'après la théorie des probabilités et des statistiques qu'à mesure que le nombre de fois que le client appelle le serveur augmente, l'effet réel se rapproche de plus en plus d'une répartition uniforme des appels vers chaque serveur dans le backend, ce qui est le résultat d'un sondage. .
L'implémentation du code de la méthode aléatoire est à peu près la suivante :
L'idée globale du code est cohérente avec la méthode d'interrogation. Le serverMap est d'abord reconstruit, puis la liste des serveurs est reconstruite. obtenu. Lors de la sélection d'un serveur, utilisez la méthode nextInt de Random pour prendre une valeur aléatoire comprise entre 0 et keyList.size(), obtenant ainsi aléatoirement une adresse de serveur à partir de la liste de serveurs et la renvoyant. Selon la théorie des statistiques probabilistes, plus le débit est élevé, plus l'effet de l'algorithme aléatoire est proche de celui de l'algorithme d'interrogation.import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * @author [email protected] * @date 二月 07, 2017 */ class Random { public static String getServer() { // 重建一个Map,避免服务器的上下线导致的并发问题 Map<String, Integer> serverMap = new HashMap<String, Integer>(); serverMap.putAll(IpMap.serverWeightMap); // 取得Ip地址List Set keySet = serverMap.keySet(); ArrayList keyList = new ArrayList(); keyList.addAll(keySet); java.util.Random random = new java.util.Random(); int randomPos = random.nextInt(keyList.size()); return keyList.get(randomPos); } }
Méthode de hachage d'adresse source (Hash)
L'idée du hachage d'adresse source est d'obtenir une valeur calculée via une fonction de hachage basée sur l'adresse IP du client, et d'utiliser cette valeur pour comparer la liste des serveurs Effectuez une opération modulo sur la taille, et le résultat est le numéro de série auquel le client souhaite accéder au serveur. La méthode de hachage de l'adresse source est utilisée pour l'équilibrage de charge. Les clients avec la même adresse IP seront mappés sur le même serveur back-end pour y accéder à chaque fois que la liste des serveurs back-end reste inchangée.
L'implémentation du code de l'algorithme de hachage d'adresse source est à peu près la suivante :
Les deux premières parties sont les mêmes que la méthode d'interrogation et la méthode aléatoire. La différence réside dans le. partie de routage. Obtenez sa valeur de hachage via l'IP du client, c'est-à-dire remoteIp, et modulo la taille de la liste des serveurs. Le résultat est la valeurimport java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * @author [email protected] * @date 二月 07, 2017 */ class Hash { public static String getServer() { // 重建一个Map,避免服务器的上下线导致的并发问题 Map<String, Integer> serverMap = new HashMap<String, Integer>(); serverMap.putAll(IpMap.serverWeightMap); // 取得Ip地址List Set keySet = serverMap.keySet(); ArrayList keyList = new ArrayList(); keyList.addAll(keySet); // 在Web应用中可通过HttpServlet的getRemoteIp方法获取 String remoteIp = "127.0.0.1"; int hashCode = remoteIp.hashCode(); int serverListSize = keyList.size(); int serverPos = hashCode % serverListSize; return keyList.get(serverPos); } }
du serveur sélectionné dans la liste des serveurs. L'avantage du hachage d'adresse source est qu'il garantit que la même adresse IP client sera hachée sur le même serveur backend jusqu'à ce que la liste des serveurs backend change. Selon cette fonctionnalité, une session avec état peut être établie entre les consommateurs de services et les fournisseurs de services.
源地址哈希算法的缺点在于:除非集群中服务器的非常稳定,基本不会上下线,否则一旦有服务器上线、下线,那么通过源地址哈希算法路由到的服务器是服务器上线、下线前路由到的服务器的概率非常低,如果是session则取不到session,如果是缓存则可能引发"雪崩"。如果这么解释不适合明白,可以看我之前的一篇文章MemCache超详细解读,一致性Hash算法部分。
加权轮询(Weight Round Robin)法
不同的后端服务器可能机器的配置和当前系统的负载并不相同,因此它们的抗压能力也不相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请;而配置低、负载高的机器,给其分配较低的权重,降低其系统负载,加权轮询能很好地处理这一问题,并将请求顺序且按照权重分配到后端。加权轮询法的代码实现大致如下:
import java.util.*; /** * @author [email protected] * @date 二月 07, 2017 */ class WeightRoundRobin { private static Integer pos; public static String getServer() { // 重建一个Map,避免服务器的上下线导致的并发问题 Map<String, Integer> serverMap = new HashMap<String, Integer>(); serverMap.putAll(IpMap.serverWeightMap); // 取得Ip地址List Set keySet = serverMap.keySet(); Iterator iterator = keySet.iterator(); List serverList = new ArrayList(); while (iterator.hasNext()) { String server = iterator.next(); int weight = serverMap.get(server); for (int i = 0; i < weight; i++) serverList.add(server); } String server = null; synchronized (pos) { if (pos > keySet.size()) pos = 0; server = serverList.get(pos); pos ++; } return server; } }
与轮询法类似,只是在获取服务器地址之前增加了一段权重计算的代码,根据权重的大小,将地址重复地增加到服务器地址列表中,权重越大,该服务器每轮所获得的请求数量越多。
加权随机(Weight Random)法
与加权轮询法一样,加权随机法也根据后端机器的配置,系统的负载分配不同的权重。不同的是,它是按照权重随机请求后端服务器,而非顺序。
import java.util.*; /** * @author [email protected] * @date 二月 07, 2017 */ class WeightRandom { public static String getServer() { // 重建一个Map,避免服务器的上下线导致的并发问题 Map<String, Integer> serverMap = new HashMap<String, Integer>(); serverMap.putAll(IpMap.serverWeightMap); // 取得Ip地址List Set keySet = serverMap.keySet(); Iterator iterator = keySet.iterator(); List serverList = new ArrayList(); while (iterator.hasNext()) { String server = iterator.next(); int weight = serverMap.get(server); for (int i = 0; i < weight; i++) serverList.add(server); } java.util.Random random = new java.util.Random(); int randomPos = random.nextInt(serverList.size()); return serverList.get(randomPos); } }
这段代码相当于是随机法和加权轮询法的结合,比较好理解,就不解释了。
最小连接数(Least Connections)法
最小连接数算法比较灵活和智能,由于后端服务器的配置不尽相同,对于请求的处理有快有慢,它是根据后端服务器当前的连接情况,动态地选取其中当前
积压连接数最少的一台服务器来处理当前的请求,尽可能地提高后端服务的利用效率,将负责合理地分流到每一台服务器。
前面几种方法费尽心思来实现服务消费者请求次数分配的均衡,当然这么做是没错的,可以为后端的多台服务器平均分配工作量,最大程度地提高服务器的利用率,但是实际情况是否真的如此?实际情况中,请求次数的均衡真的能代表负载的均衡吗?这是一个值得思考的问题。
上面的问题,再换一个角度来说就是:以后端服务器的视角来观察系统的负载,而非请求发起方来观察。最小连接数法便属于此类。
最小连接数算法比较灵活和智能,由于后端服务器的配置不尽相同,对于请求的处理有快有慢,它正是根据后端服务器当前的连接情况,动态地选取其中当前积压连接数最少的一台服务器来处理当前请求,尽可能地提高后端服务器的利用效率,将负载合理地分流到每一台机器。由于最小连接数设计服务器连接数的汇总和感知,设计与实现较为繁琐,此处就不说它的实现了。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Guide du nombre parfait en Java. Nous discutons ici de la définition, comment vérifier le nombre parfait en Java ?, des exemples d'implémentation de code.

Guide de Weka en Java. Nous discutons ici de l'introduction, de la façon d'utiliser Weka Java, du type de plate-forme et des avantages avec des exemples.

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

Guide de TimeStamp to Date en Java. Ici, nous discutons également de l'introduction et de la façon de convertir l'horodatage en date en Java avec des exemples.

Les capsules sont des figures géométriques tridimensionnelles, composées d'un cylindre et d'un hémisphère aux deux extrémités. Le volume de la capsule peut être calculé en ajoutant le volume du cylindre et le volume de l'hémisphère aux deux extrémités. Ce tutoriel discutera de la façon de calculer le volume d'une capsule donnée en Java en utilisant différentes méthodes. Formule de volume de capsule La formule du volume de la capsule est la suivante: Volume de capsule = volume cylindrique volume de deux hémisphères volume dans, R: Le rayon de l'hémisphère. H: La hauteur du cylindre (à l'exclusion de l'hémisphère). Exemple 1 entrer Rayon = 5 unités Hauteur = 10 unités Sortir Volume = 1570,8 unités cubes expliquer Calculer le volume à l'aide de la formule: Volume = π × r2 × h (4

Java est un langage de programmation populaire qui peut être appris aussi bien par les développeurs débutants que par les développeurs expérimentés. Ce didacticiel commence par les concepts de base et progresse vers des sujets avancés. Après avoir installé le kit de développement Java, vous pouvez vous entraîner à la programmation en créant un simple programme « Hello, World ! ». Une fois que vous avez compris le code, utilisez l'invite de commande pour compiler et exécuter le programme, et « Hello, World ! » s'affichera sur la console. L'apprentissage de Java commence votre parcours de programmation et, à mesure que votre maîtrise s'approfondit, vous pouvez créer des applications plus complexes.
