Почему подсчет доступа? Мой предыдущий личный блог был Bu Suanzi для подсчета посещения сайта, что было очень хорошим, но ответ был медленным в течение многих раз. Во -вторых, мой личный блог был слишком мало, чтобы получить доступ, и данные не были хороши, чтобы смотреть ?…
В предыдущем сообщении в блоге кратко представили конфигурацию и использование Redistemplate весной. Эта статья считается простым случаем приложения, в основном на основе счетчиков Redis для реализации статистики.
I. Дизайн
Простой счетчик доступа в основном использует хэш -структуру Redis, а соответствующая структура хранения следующая:
Структура хранения относительно проста. Чтобы развернуть, каждое приложение (или сайт) соответствует приложению, а затем на странице статистики на основе пути пути. Наконец, существует специальное количество доступа для указания всего сайта.
II Выполнение
Главное - использовать хэш -структуру Redis, а затем реализовать статистику данных. Это не так сложно. Вы можете ссылаться на среду Redis в весенней среде:
Настройка Spring Redistemplate и использование
1. Класс инкапсуляции Redis
Для нескольких часто используемых мы сделали простую инкапсуляцию, и мы напрямую используем метод Excut Redistemplate. Конечно, мы также можем использовать Template.OpsForValue () и другие удобные методы. Здесь мы используем JSON для сериализации и десериализации объектов.
Public Class QuickRedisclient {Private Static Final Chad Code = charset.forname ("UTF-8"); Частный статический Redistemplate <String, String> Template; public static void Register (Redistemplate <String, String> Template) {Quickredisclient.template = Template; } public static void nullcheck (Object ... args) {for (Object obj: args) {if (obj == null) {бросить новый allosalArgumentException ("Redis Argemt не может быть нулевым!"); }}} public static byte [] tobytes (string key) {nullcheck (key); return 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? 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 Incr (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: acrov;}); } public static <t> t hget (String Key, String Field, Class <t> clz) {return template.execute ((rediscallback <t>) con -> {byte [] recorms = con.hget (tobytes (key), tobytes (field)); if (records = null) {return null;} return json.parse (inform); } public static <t> map <string, t> hmget (string key, list <string> fields, class <t> clz) {list <byte []> list = template.execute ((rediscallback <list [byte [] >>) con -> con.hmget (tobytes (key), tobytes (fields)); if (collegeutils.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; импорт org.springframework.cache.cachemanager; import org.springframework.context.nantation.beanben.smaperframeworkwork. org.springframework.context.annotation.propertySource; import org.springframework.core.env.environment; import org.springframework.data.redis.cache.rediscachemanager; import.springframework.data.redis.redisconsecnectorectory; org.springframework.data.redis.connection.redispassword; import org.springframework.data.redis.connection.lettuce.LleceConnectionFactory; импорт org.springframework.data.redis.core.redistemptorate;/*** Создан Yihui в 18:45 18/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6/6. */@Configuration@propertysource (value = "classpath: application.yml") открытый класс redisconf {частная конечная среда окружающей среды; public redisconf (окружающая среда) {this.environment = среда; } @Bean public cachemanager cachemanager () {return rediscachemanager.rediscachamanagerbuilder.fromconnectionFactory (redisconnectionFactory ()). Build (); } @Bean public redistemplate <string, string> redistemplate (redisconnectionfactory redisconnectionFactory) {redistemplate <string, string> redistemplate = new Redistemplate <> (); Redistemplate.setConnectionFactory (RedisconnectionFactory); Default Trserializer Serializer = новый Defaltstrserializer (); redistemplate.setValueserializer (сериализатор); redistemplate.sethashvalueserializer (сериализатор); Redistemplate.setKeySerializer (сериализатор); redistemplate.sethashkeyserializer (сериализатор); redistemplate.afterpropertiesset (); Quickredisclient.register (Redistemplate); вернуть Redistemplate; } @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.fterpropertiesset (); вернуть лицо; }} 2. Поддержка контроллера
Сначала определите параметры запроса:
@Datapublic class webcountreqdo реализует serializable {private String appkey; Приватная строка реферат;}Второе - реализовать интерфейс контроллера. Обратите немного внимания на логику подсчета в соответствии с пути:
@Slf4j@restcontroller@requestmapping (path = "/count") public class webcountcontroller {@requestmapping (path = "cc", method = {requestmethod.get}) public responsewrapper <coundTto> addCount (webCountReqdo webCountReqdo) {string appkey = webCountrequequequequequequequek if (stringUtils.isblank (appkey)) {return responsewrapper.errorreturnmix (status.statusenum.illegal_params_mix, «Укажите Appkey!»); } String referer = reqInfoContext.getReqinfo (). GetReerer (); if (stringUtils.isblank (referer)) {referer = webcountreqdo.getReerer (); } if (stringUtils.isblank (referer)) {return responsewrapper.errorreturnmix (status.statusenum.fail_mix, "не может получить запрос!"); } return responsewrapper.successreturn (doupdatecnt (appkey, referer)); } private countdto doupdatecnt (string appkey, string referer) {try {if (! Referer.StartSwith ("http")) {referer = "https: //" + referer; } Uri uri = new uri (реферат); String host = uri.gethost (); String path = uri.getPath (); long count = Quickredisclient.hincr (Appkey, Path, 1); Long Total = QuickRedisclient.hincr (Appkey, Host, 1); вернуть новый countdto (count, total); } catch (Exception e) {log.error ("Получить ошибку пути реферата! Рефера: {}, e: {}", реферат, e); вернуть новый CountDTO (1L, 1L); }}}Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.