액세스가 계산되는 이유는 무엇입니까? 이전의 개인 블로그는 사이트 방문 카운팅을위한 Bu Suanzi였습니다. 매우 좋았지 만 응답은 여러 번 느 렸습니다. 둘째, 내 개인 블로그는 액세스하기에는 너무 적었고 데이터는보기 좋지 않았습니다.
이전 블로그 게시물은 봄에 Redistemplate의 구성 및 사용을 간략하게 소개했습니다. 이 기사는 주로 통계를 구현하기위한 Redis 카운터를 기반으로 간단한 신청 사례로 간주됩니다.
I. 디자인
간단한 액세스 카운터는 주로 Redis의 해시 구조를 사용하며 해당 스토리지 구조는 다음과 같습니다.
저장 구조는 비교적 간단합니다. 확장하려면 각 응용 프로그램 (또는 사이트)은 앱에 해당 한 다음 경로 경로를 기반으로 통계를 페이지에 빠뜨립니다. 마지막으로 전체 사이트를 진술 할 특별 액세스 수가 있습니다.
II. 구현
가장 중요한 것은 Redis의 해시 구조를 사용한 다음 데이터 통계를 구현하는 것입니다. 너무 어렵지 않습니다. 스프링 환경에서 Redis 환경을 참조 할 수 있습니다.
Spring의 Redistemplate 구성 및 사용
1. Redis 캡슐화 클래스
일반적으로 사용되는 몇 가지의 경우 간단한 캡슐화를 만들었고 Redistemplate의 Excut 방법을 직접 사용합니다. 물론 Template.opSforValue () 및 기타 편리한 방법을 사용할 수도 있습니다. 여기서 우리는 json을 사용하여 객체를 직렬화하고 사로화합니다.
공개 클래스 QuickRedisClient {private static final charset code = charset.forname ( "utf-8"); 비공개 정적 레디 스템 플레이트 <문자열, 문자열> 템플릿; public static void Register (redistemplate <string, string> 템플릿) {QuickRedisClient.template = 템플릿; } public static void nullCheck (object ... args) {for (object obj : args) {if (obj == null) {새로운 불법 불법 행위 렉싱 ( "redis argument는 null!"); }}} public static byte [] tobytes (문자열 키) {nullCheck (키); return key.getBytes (코드); } public static bd int index = 0; for (문자열 키 : 키) {bytes [index ++] = 토비 (키); } 반환 바이트; } public static string getst (문자열 키) {return template.execute ((readiscallback <string>) con-> {byte [] val = con.get (tobytes (key)); return val == null? null : new String (val);}); } public static void putstr (문자열 키, 문자열 값) {template.execute ((readiscallback <void>) con-> {con.set (tobytes (key), tobytes (value)); return null;}); } public static long exc (문자열 키, long add) {return template.execute ((readiscallback <long>) con-> {long record = con.incrby (Tobytes (키), 추가); retud record == null? 0l : record;}); } public static long hincr (문자열 키, 문자열 필드, long add) {return template.execute ((readiscallback <long>) con-> {long record = con.hincrby (Tobytes (키), 토비 (필드), 추가); retud record == null? 0l : record;}); } public static <t> t hget (문자열 키, 문자열 필드, 클래스 <t> clz) {return template.execute ((Rediscallback <t>) con-> {byte [] records = con.hget (key), tobytes (field)); if (records == null) {return null;}) } public static <t> map <string, t> hmget (문자열 키, list <string> 필드, 클래스 <t> clz) {list <byte []> list = template.execute ((readiscallback <list <byte [] >>) con.hmget (tobytes (key), tobytes (fields)); if (collectionUtils.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); } 반환 결과; }} 해당 구성 클래스
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.annotation.bean; import org.springframework.context.annotation.configuration; import org.springframework.context.annotation.propertysource; import org.springframework.core.env.environment; import org.spramework.data.redis.cache.rediscachemanager; org.springframework.data.redis.connection.redisconnectionfactory; import org.springframework.data.redis.connection.redispassword; import org.springframework.data.redis.connection.lettuce.lettuceConcection factory; import org.springframework.redata.redistepter; 18:45 18/6/11의 Yihui. */@configuration@propertySource (value = "classpath : application.yml") public class readisconf {개인 최종 환경 환경; Public readisconf (환경 환경) {this.environment = 환경; } @bean public cachemanager cachemanager () {return return return retiscacheManager.rediscacheManagerBuilder.fromConnectionFactory (readiscOntectionFactory ()). build (); } @bean public redistemplate <string, String> redistemplate (readisconnectionFactory readiscOntectionFactory) {redistemplate <String, String> redistemplate = new redistemplate <> (); redistemplate.setConnectionFactory (readisconnectionFactory); defaultstrserializer serializer = new defaultstrserializer (); redistemplate.setValueserializer (Serializer); Redistemplate.SethashValueserializer (Serializer); redistemplate.setKeyserializer (Serializer); Redistemplate.Sethashkeyserializer (Serializer); redistemplate.afterProperTiesset (); QuickRedisclient.register (RedistemPlate); redistemplate를 반환합니다. } @bean public readisconnectionfactory readisconnectionfactory () {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.fterProperTiesset (); 반환 얼굴; }} 2. 컨트롤러 지원
먼저 요청 매개 변수를 정의합니다.
@datapublic 클래스 WebCountReqdo는 시리얼이 가능성 {private String appkey; 개인 문자열 참조;}두 번째는 컨트롤러 인터페이스를 구현하는 것입니다. 경로에 따라 계산의 논리에 약간주의를 기울이십시오.
@slf4j@restcontroller@restontroller (path = "/count") public class webCountController {@RequestMapping (path = "cc", method = {requestMethod.get}) public responsewrapper <countdto> addCount (webCountReqDO webCountReqDO) {string appkey = webcountrdo (); if (stringUtils.isblank (appkey)) {return responsewrapper.errerreturnmix (status.statusenum.illegal_params_mix, "appkey를 지정하십시오!"); } stringer = reqinfoconText.getReqInfo (). getReferer (); if (stringUtils.isBlank (CERERER)) {referer = webCountReqDo.getReferer (); } if (stringUtils.isBlank (CEERTER)) {return responseWrapper.erReReturnMix (status.statusenum.fail_mix, "requester!"); } return responsewrapper.successreturn (doupdatecnt (Appkey, Cereper)); } private countdto doupdatecnt (String appkey, String Referer) {try {if (! referer.startswith ( "http")) {referer = "https : //" + referer; } uri uri = new uri (참조); 문자열 호스트 = uri.gethost (); 문자열 path = uri.getPath (); long count = QuickRedisclient.hincr (Appkey, Path, 1); Long Total = QuickRedisclient.hincr (Appkey, Host, 1); 새로운 countdto (count, total)를 반환합니다. } catch (예외 e) {log.error ( "참조 경로 오류 오류! 새로운 Countdto (1L, 1L)를 반환합니다. }}}위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.