Pourquoi un nombre d'accès? Mon blog personnel précédent était Bu Suanzi pour le comptage des visites sur le site, ce qui était très bon, mais la réponse a été lente à plusieurs reprises. Deuxièmement, mon blog personnel était trop peu nombreux pour accéder et les données n'étaient pas bonnes à regarder ?…
L'article de blog précédent a brièvement introduit la configuration et l'utilisation de Redemplate au printemps. Cet article est considéré comme un cas de candidature simple, principalement basé sur les compteurs Redis pour mettre en œuvre des statistiques.
I. Concevoir
Un compteur d'accès simple utilise principalement la structure de hachage de Redis, et la structure de stockage correspondante est la suivante:
La structure de stockage est relativement simple. Afin de se développer, chaque application (ou site) correspond à une application, puis pagine les statistiques basées sur le chemin du chemin. Enfin, il existe un nombre d'accès spécial pour indiquer l'ensemble du site.
Ii Mise en œuvre
L'essentiel est d'utiliser la structure de hachage de Redis, puis de mettre en œuvre des statistiques de données. Ce n'est pas trop difficile. Vous pouvez vous référer à l'environnement Redis dans l'environnement printanier:
Configuration et utilisation de Spring Redemplate
1. Classe d'encapsulation redis
Pour plusieurs couramment utilisés, nous avons fait une encapsulation simple et nous utilisons directement la méthode excut de Redemplate. Bien sûr, nous pouvons également utiliser Template.OpsForValue () et d'autres méthodes pratiques. Ici, nous utilisons JSON pour sérialiser et désérialiser les objets.
classe publique QuickRedIsclient {private static final charset code = charset.forname ("utf-8"); Template statique privé statique <string, string>; Registre publique de void statique (Redistemplate <String, String> modèle) {QuickRedisclient.Template = modèle; } public static void nullCheck (objet ... args) {for (objet obj: args) {if (obj == null) {lancer un nouveau illégalargumentException ("l'argument redis ne peut pas être null!"); }}} octet statique public [] tobytes (string key) {nullCheck (key); return key.getBytes (code); } byte statique public [] [] tobytes (list <string> touches) {byte [] [] bytes = new byte [keys.size ()] []; int index = 0; for (String Key: Keys) {Bytes [index ++] = tobytes (key); } retour des octets; } public static String gettr (string key) {return template.execute ((redisCallback <string>) con -> {byte [] val = con.get (tobytes (key)); return val = null? null: new String (val);}); } public static void putstr (string key, string value) {template.execute ((redisCallback <void>) con -> {con.set (tobytes (key), tobytes (valeur)); return null;}); } public static long incr (string key, long ajouter) {return template.execute ((rediscallback <fong>) con -> {long enregistre = con.incrby (tobytes (key), add); return enregistrer == null? 0l: enregistrement;}); } public static long hincr (key string, champ de chaîne, long add) {return template.execute ((rediscallback <long>) con -> {long enregistre = con.hincrby (tobytes (key), tobytes (champ), add); return record == null? 0l: record;}); } public static <t> t hget (clé de chaîne, champ de chaîne, classe <t> clz) {return template.execute ((redisCallback <t>) con -> {byte [] enregistres = con.hget (tobytes (key), tobytes (champ)); if (enregistres == null) {return null;} return json.parseObject (disques, clz); } public static <t> map <string, t> hmget (string key, list <string> champs, class <t> clz) {list <byte []> list = template.execute ((rediscallback <list <byte [] >>) con -> con.hmget (tobytes (key), toBytes (fields))); if (CollectionUtils.Isempty (list)) {return Collection.EmptyMap (); } Map <string, t> result = new hashmap <> (); for (int i = 0; i <fields.size (); i ++) {if (list.get (i) == null) {continue; } result.put (fields.get (i), json.parseObject (list.get (i), clz)); } Retour Résultat; }} Classe de configuration correspondante
package com.git.hui.story.cache.redis; import com.git.hui.story.cache.redis.serializer.defaultStrserializer; import org.springframework.cache.cachemanager; import org.springframework.context.anotation.bean; import org.springframework org.springframework.context.annotation.propertysource; import org.springframework.core.env.environment; import org.springframework.data.redis.cache.recachemanager; import org.springframework.data.redis.connection.redisconnectionfactory; org.springframework.data.redis.connection.redispassword; import org.springframework.data.redis.connection.lettuce.lettuceconnectionfactory; import org.springframework.data.redis.core.redistemplate; / ** * créé par yihui en 18:45 18/6/11. * / @ Configuration @ propriétéSource (value = "classpath: application.yml") public class re-onConf {private final Environment Environment; Public RedisConf (environnement environnement) {this.environment = environnement; } @Bean public cacheManager CacheManager () {return rediscacheManager.rediscacheManagerBuilder.FromConnectionFactory (redisconnectionfactory ()). Build (); } @Bean public redesttemplate <String, String> redesttemplate (redisconnectionfactory redisconnectionfactory) {redemplate <string, string> redetemplate = new reistetemplate <> (); Redistetemplate.SetConnectionFactory (RedisconnectionFactory); DefaultStRerializer Serializer = new defaultStRerializer (); Redistemplate.setValueSerializer (sérialiseur); Redemplate.SethashValueSerializer (sérialiseur); redemplate.setKeySerializer (sérialiseur); Redemplate.SethashKeySerializer (sérialiseur); reidemplate.afterpropertiesset (); QuickRedisclient.Register (Redemplate); retour redestemplate; } @Bean public redisconnectionfactory redisconnectionFactory () {LetTuceConnectionFactory fac = new LetTuceConnectionFactory (); fac.getStandalonEconfiguration (). SethostName (Environment.getProperty ("Spring.redis.host")); fac.getStandalonEconfiguration (). Setport (Integer.ParseInt (Environment.getProperty ("Spring.redis.port"))); fac.getStandalonEconfiguration (). SetPassword (redispassword.of (Environment.getProperty ("Spring.redis.password"))); fac.AfterPropertiseSet (); Retour FAC; }} 2. Prise en charge du contrôleur
Définissez d'abord les paramètres de demande:
@Datapublic class webcountreqdo implémente Serializable {private String AppKey; référence de chaîne privée;}La seconde consiste à implémenter l'interface du contrôleur. Faites un peu attention à la logique de compter en fonction du chemin:
@ Slf4j @ restController @ requestmapping (path = "/ count") public class webCountController {@RequestMapping (path = "cc", méthode = {requestMethod.get}) public réponsewrapper <CountDto> AddCount (webcountreqdo webCountreqdo) {string appkey = webcountreqdo.getAppkey;); if (stringUtils.isblank (appkey)) {return réponsewrapper.errorreturnmix (status.statusenum.illegal_params_mix, "Veuillez spécifier AppKey!"); } String référer = reqinfoconText.getReqInfo (). GetReferrer (); if (stringUtils.isblank (référer)) {référer = webcountreqdo.getReferrer (); } if (stringUtils.isblank (référer)) {return réponsewrapper.errorReturnmix (status.statusenum.fail_mix, "Impossible d'obtenir le demandeur!"); } return réponsewrapper.succesReturn (DoupDatecnt (appkey, référence)); } private countdto doupdatecnt (String AppKey, String référer) {try {if (! référer.startswith ("http")) {référer = "https: //" + référer; } Uri uri = new uri (référence); String host = uri.gethost (); String path = uri.getPath (); Long Count = QuickRedisclient.hincr (Appkey, Path, 1); Long Total = QuickRedisclient.hincr (Appkey, hôte, 1); retourner new Countdto (comte, total); } catch (exception e) {Log.Error ("Get Reférer Path Error! Référer: {}, e: {}", référer, e); retourner nouveau countdto (1l, 1l); }}}Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.