なぜアクセスがカウントされるのですか?私の以前の個人的なブログは、サイト訪問カウントのためのBu Suanziでしたが、これは非常に良かったですが、応答は何度も遅かったです。第二に、私の個人的なブログはアクセスできないほど少なすぎて、データは良くありませんでした。
以前のブログ投稿では、春にRedistemplateの構成と使用を簡単に紹介しました。この記事は、主に統計を実装するためのRedisカウンターに基づいて、単純なアプリケーションケースと見なされます。
I.デザイン
単純なアクセスカウンターは、主にRedisのハッシュ構造を使用し、対応するストレージ構造は次のとおりです。
ストレージ構造は比較的簡単です。拡張するために、各アプリケーション(またはサイト)がアプリに対応し、パスパスに基づいて統計をページングします。最後に、サイト全体を述べるための特別なアクセス数があります。
ii。実装
主なことは、Redisのハッシュ構造を使用して、データ統計を実装することです。それほど難しくありません。春の環境でRedis環境を参照できます。
SpringのRedistemplateの構成と使用
1。Redisカプセル化クラス
いくつかの一般的に使用されるものについては、単純なカプセル化を行い、エクスキャットメソッドのRedistemplateを直接使用しています。もちろん、template.opsforvalue()およびその他の便利な方法も使用できます。ここでは、JSONを使用してオブジェクトをシリアル化して脱気にします。
パブリッククラスQuickRedisclient {private static final charset code = charset.forname( "utf-8"); private static redistemplate <string、string>テンプレート; public static voidレジスタ(redistemplate <string、string> template){QuickRediscLient.Template = Template; } public static void nullcheck(object ... args){for(object obj:args){if(obj == null){show new IllegalargumentException( "Redis引数はnull!"); }}} public static byte [] tobytes(string key){nullcheck(key); key.getBytes(code)を返します。 } public static byte [] [] tobytes(list <string> keys){byte [] [] bytes = new byte [keys.size()] []; int index = 0; for(string key:keys){bytes [index ++] = tobytes(key); }バイトを返します。 } public static string getStr(string key){return template.execute((rediscallback <string>)con-> {byte [] val = con.get(tobytes(key)); return val == null:new string(val);}); } public static void putStr(string key、string value){template.execute((rediscallback <void>)con-> {con.set(tobytes(key)、tobytes(value)); return null;}); } public static long incre(string key、long add){return template.execute((rediscallback <long>)con-> {long record = con.incrby(tobytes(key)、add); return record == null?0l:record;}); } public static long hincr(string key、string field、long add){return template.execute((rediscallback <long>)con-> {long record = con.hincrby(tobytes(key)、tobytes(field)、add); return Record == null?0l:record;}); } public static <t> t hget(string key、string field、class <t> clz){return template.execute((rediscallback <t>)con-> {byte [] con.hget(tobytes(key)、tobytes(key)); } public static <t> map <string、t> hmget(string key、list <string> fields、class <t> clz){list <byte []> list = template.execute((rediscallback <byte [] >>)con-> con.hmget(tobytes(key)、tobytes(fields)); if(collectutils.isempty(list)){return collections.emptymap(); } map <string、t> result = new Hashmap <>(); for(int i = 0; i <fields.size(); i ++){if(list.get(i)== null){継続; } result.put(fields.get(i)、json.parseobject(list.get(i)、clz)); } return result; }}対応する構成クラス
パッケージcom.git.hui.story.cache.redis; Import com.git.hui.story.cache.redis.serializer.defaultStrserializer; Import org.springframework.cacheer; Import org.springframework.context.annotation.Annotation.Bean; org.springframework.context.annotation.configuration; import org.springframework.context.annotation.propertysource; Import org.springframework.core.env.environment; Import org.springframework.data.redis.cache.rediscachemanager; org.springframework.data.redis.connection.redisconnectionFactory; Import org.springframework.data.redis.connection.redispassword; Import org.springframework.data.redis.connection.conection.lettuce.lettuceConnectionory; Import; org.springframework.data.redis.core.redistemplate;/*** 18:45 18/6/11にYihuiによって作成されました。 */@configuration@propertySource(value = "classpath:application.yml")public class redisconf {プライベート最終環境環境; Public Redisconf(環境環境){this.environment =環境; } @bean public cachemanager cachemanager(){return rediscachemanager.rediscachemanagerbuilder.fromConnectionFactory(redisconnectionFactory())。build(); } @bean public redistemplate <string、string> redistemplate(redisconnectionFactory redisconnectionFactory){redistemplate <string、string> redistemplate = new Redistemplate <>(); redistemplate.setConnectionFactory(RedisconnectionFactory); DefaultStrserializer serializer = new DefaultStrserializer(); redistemplate.setValueSerializer(Serializer); redistemplate.sethashvalueserializer(serializer); redistemplate.setkeyserializer(serializer); redistemplate.sethashkeyserializer(serializer); redistemplate.afterpropertiesset(); QuickRedisclient.register(Redistemplate); REDISTEMPLATEを返します。 } @bean public redisconnectionFactory redisconnectionFactory(){lettuceconnectionfactory fac = new lettuceconnectionfactory(); fac.getstandaloneconfiguration()。sethostname(entumine.getProperty( "spring.redis.host")); fac.getstandaloneconfiguration()。setport(integer.parseint(entumine.getProperty( "spring.redis.port"))); fac.getstandaloneconfiguration()。setPassWord(redispassword.of(entumine.getProperty( "spring.redis.password"))); fac.afterpropertiesset(); FACを返します。 }} 2。コントローラーサポート
最初に、リクエストパラメーターを定義します。
@datapublic class webcountreqdoはserializable {private string appkey;プライベート文字列参照者;}2つ目は、コントローラーインターフェイスを実装することです。パスに従ってカウントの論理に少し注意してください。
@slf4j@retycontroller@requestmapping(path = "/count")public class webcountcontroller {@requestmapping(@requestmapping(path = "cc"、method = {requestmethod.get})public ressonswrapper <countdto> addcount(webcountreqdo webcountreqdo) if(stringutils.isblank(appkey)){Return ResponseWrapper.ErrorreturnMix(status.statusenum.illegal_params_mix、 "appkeyを指定してください!"); } string referer = reqinfocontext.getreqinfo()。getReferer(); if(stringutils.isblank(referer)){referer = webcountreqdo.getReferer(); } if(stringutils.isblank(referer)){retunt responsewrapper.errorreturnmix(status.statusenum.fail_mix、 "requesterを取得できません!"); } RESONSEWRAPPER.SUCCESSRETURN(doupdatecnt(appkey、referer)); } private countdto doupdatecnt(string appkey、string referer){try {if(!referer.startswith( "http")){referer = "https://" + referer; } uri uri = new uri(referer); string host = uri.gethost(); string path = uri.getPath(); long count = quickredisclient.hincr(appkey、path、1);長い合計= QuickRedisclient.hincr(appkey、host、1); new countdto(count、合計)を返します。 } catch(Exception e){log.Error( "参照パスエラー!参照者:{}、e:{}"、参照、e); new countdto(1L、1L)を返します。 }}}上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。