Mengapa penghitungan akses? Blog pribadi saya sebelumnya adalah Bu Suanzi untuk penghitungan kunjungan situs, yang sangat bagus, tetapi tanggapannya lambat berkali -kali. Kedua, blog pribadi saya terlalu sedikit untuk diakses dan datanya tidak baik untuk ditonton ?…
Posting blog sebelumnya memperkenalkan konfigurasi dan penggunaan redistemplate di Spring. Artikel ini dianggap sebagai kasus aplikasi sederhana, terutama berdasarkan penghitung Redis untuk mengimplementasikan statistik.
I. Desain
Penghitung akses sederhana terutama menggunakan struktur hash redis, dan struktur penyimpanan yang sesuai adalah sebagai berikut:
Struktur penyimpanan relatif sederhana. Untuk memperluas, setiap aplikasi (atau situs) sesuai dengan aplikasi, dan kemudian statistik paginat berdasarkan jalur jalur. Akhirnya, ada jumlah akses khusus untuk menyatakan seluruh situs.
Ii. Pelaksanaan
Hal utama adalah menggunakan struktur hash redis dan kemudian mengimplementasikan statistik data. Itu tidak terlalu sulit. Anda dapat merujuk ke lingkungan Redis di lingkungan musim semi:
Konfigurasi dan Penggunaan Redistemplate Spring
1. Kelas Enkapsulasi Redis
Untuk beberapa yang umum digunakan, kami telah membuat enkapsulasi sederhana, dan kami secara langsung menggunakan metode redistemplate excut. Tentu saja, kita juga dapat menggunakan template.opsforvalue () dan metode nyaman lainnya. Di sini kami menggunakan JSON untuk membuat serial dan deserialize objek.
kelas publik QuickReDisClient {private static final charset code = charset.forname ("UTF-8"); private static redistemplate <string, string> template; Public static void register (redistemplate <string, string> template) {quickredisclient.template = template; } public static void nullCheck (objek ... args) {for (objek obj: args) {if (obj == null) {lempar baru ilegalargumentException ("argumen redis tidak bisa nol!"); }}} public static byte [] tobytes (tombol string) {nullCheck (key); return key.getBytes (kode); } public static byte [] [] tobytes (daftar <string> keys) {byte [] [] bytes = byte baru [keys.size ()] []; INT INDEX = 0; untuk (tombol string: tombol) {bytes [index ++] = tobytes (key); } return byte; } public static string getStr (tombol string) {return template.execute ((rediscallback <string>) con -> {byte [] val = con.get (tobytes (key)); return val == null? null: string baru (val);}); } public static void putstr (tombol string, nilai string) {template.execute ((rediscallback <void>) con -> {con.set (tobytes (key), tobytes (value)); return null;}); } public static long incr (tombol string, long add) {return template.execute ((rediscallback <long>) con -> {long record = con.incrby (tobytes (key), add); return record == null? 0L: Record;}); } public static long hINCR (tombol string, bidang string, 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 (tombol string, bidang string, kelas <t> clz) {return template.execute ((rediscallback <t>) con -> {byte [] catatan = con.hget (tobytes (key), tobytes (bidang)); if (catatan == null) {return null; } public static <T> Peta <string, t> hmget (tombol string, daftar <string> bidang, kelas <t> clz) {daftar <byte []> list = template.execute ((rediscallback <list <byte []>) con -> con.hmget (toBytes (key), toBytes (fiel) con -> con.hmget (toBytes (key), toBytes (fiel)) con -> con); if (collectionsils.isempty (list)) {return collections.emptyMap (); } Peta <string, t> hasil = hashmap baru <> (); untuk (int i = 0; i <fields.size (); i ++) {if (list.get (i) == null) {lanjutkan; } result.put (fields.get (i), json.parseObject (list.get (i), clz)); } hasil pengembalian; }} Kelas konfigurasi yang sesuai
Paket com.git.hui.story.cache.redis; import com.git.hui.story.cache.redis.serializer.defaultStrserializer; impor org.springframework.cache.cachegerer; impor org.springframework.context.annotation.cachean; org.springframework.context.annotation.propertysource; impor org.springframework.core.env.environment; Impor org.springframework.data.redis.cache.cachecinger; org.springframework.data.redis.connection.redispassword; impor org.springframework.data.redis.connection.lettuce.lettuceconnectionFactory; impor org.springframework.data.redis.core.core.redistemple; */@Configuration@propertiesource (value = "classpath: application.yml") kelas publik redisconf {private final lingkungan lingkungan; redisconf publik (lingkungan lingkungan) {this.environment = lingkungan; } @Bean CacheManager Cachemanager () {return receScachemanager.rediscacheManagerBuilder.FromConnectionFactory (RedisconnectionFactory ()). Build (); } @Bean redistemplate publik <string, string> redistemplate (redisconnectionFactory redisconnectionFactory) {redistemplate <string, string> redistemplate = redistemplate baru <> (); redistemplate.setConnectionFactory (RedisconnectionFactory); DefaultStrSerializer Serializer = New DefaultStrSerializer (); redistemplate.setValueserializer (serializer); redistemplate.sethashValueserializer (serializer); redistemplate.setkeyserializer (serializer); redistemplate.sethashkeyserializer (serializer); redistemplate.afterpropertiesset (); QuickredisClient.Register (redistemplate); return redistemplate; } @Bean Public RedisconnectionFactory RedisconnectionFactory () {LettuCeConnectionFactory fac = new LettuCeConnectionFactory (); fac.getstandAnoneConfiguration (). SetHostName (lingkungan.getProperty ("spring.redis.host")); fac.getstandAloneConfiguration (). Setport (integer.parseint (lingkungan.getProperty ("spring.redis.port"))); fac.getstandAnoneConfiguration (). SetPassword (redispassword.of (lingkungan.getProperty ("spring.redis.password"))); fac.afterpropertiesset (); fac kembali; }} 2. Dukungan pengontrol
Pertama, tentukan parameter permintaan:
@DataPublic Class WebCountreQDo mengimplementasikan serial {private string appkey; referer string pribadi;}Yang kedua adalah mengimplementasikan antarmuka pengontrol. Berikan sedikit perhatian pada logika penghitungan sesuai dengan jalan:
@Slf4j@restcontroller@requestMapping (path = "/count") Kelas publik WebCountController {@RequestMapping (path = "cc", Method = {requestMethod.get}) response publicrapper <countdto> addCount (webcouncheqdo webcouncoEntreqdo) {countdto> addcount (webcounceQdo WebCouncoEntreqdo) {string) {string) {countdo; if (stringutils.isblank (appkey)) {return responseewrapper.errorreturnmix (status.statusenum.illegal_params_mix, "Harap tentukan appkey!"); } String referer = reqinfocontext.getReqInfo (). GetReferer (); if (stringutils.isblank (referer)) {referer = webcountreqdo.getReferer (); } if (stringutils.isBlank (referer)) {return responseewrapper.errorreturnmix (status.statusenum.fail_mix, "tidak bisa mendapatkan pemohon!"); } return responseWrapper.successreturn (doupDateCnt (appkey, referer)); } private countdto doupDateCnt (string appkey, string referer) {try {if (! Referer.startswith ("http")) {referer = "https: //" + referer; } Uri uri = Uri baru (referer); Host string = uri.getHost (); String path = uri.getPath (); jumlah panjang = QuickReDisClient.hincr (Appkey, Path, 1); Total Long = QuickReDisClient.HINCR (Appkey, Host, 1); mengembalikan Countdto baru (Count, Total); } catch (exception e) {log.error ("Dapatkan kesalahan jalur referer! Referer: {}, e: {}", referer, e); mengembalikan Countdto baru (1L, 1L); }}}Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.