ทำไมการเข้าถึงจึงนับ? บล็อกส่วนตัวก่อนหน้าของฉันคือ Bu Suanzi สำหรับการเข้าชมไซต์ซึ่งเป็นสิ่งที่ดีมาก แต่การตอบสนองช้าหลายครั้ง ประการที่สองบล็อกส่วนตัวของฉันมีน้อยเกินไปที่จะเข้าถึงและข้อมูลไม่ดีที่จะดู? ...
โพสต์บล็อกก่อนหน้านี้แนะนำการกำหนดค่าและการใช้ Redistemplate สั้น ๆ ในฤดูใบไม้ผลิ บทความนี้ถือเป็นกรณีแอปพลิเคชันที่ง่ายส่วนใหญ่ขึ้นอยู่กับเคาน์เตอร์ Redis เพื่อใช้สถิติ
I. ออกแบบ
ตัวนับการเข้าถึงอย่างง่ายส่วนใหญ่ใช้โครงสร้างแฮชของ Redis และโครงสร้างการจัดเก็บที่สอดคล้องกันมีดังนี้:
โครงสร้างการจัดเก็บค่อนข้างง่าย เพื่อขยายแต่ละแอปพลิเคชัน (หรือไซต์) สอดคล้องกับแอพแล้วจึงแบ่งสถิติตามเส้นทางพา ธ ในที่สุดก็มีจำนวนการเข้าถึงพิเศษสำหรับการระบุเว็บไซต์ทั้งหมด
ii. การดำเนินการ
สิ่งสำคัญคือการใช้โครงสร้างแฮชของ Redis จากนั้นใช้สถิติข้อมูล มันไม่ยากเกินไป คุณสามารถอ้างถึงสภาพแวดล้อมของ Redis ในสภาพแวดล้อมฤดูใบไม้ผลิ:
การกำหนดค่าและการใช้งาน Redistemplate ของ Spring
1. คลาส encapsulation redis
สำหรับคนที่ใช้กันทั่วไปหลายคนเราได้ทำการห่อหุ้มอย่างง่ายและเราใช้วิธีการ excut ของ redistemplate โดยตรง แน่นอนเรายังสามารถใช้ template.opsforvalue () และวิธีการที่สะดวกอื่น ๆ ที่นี่เราใช้ JSON เพื่อทำให้เป็นอนุกรมและ deserialize วัตถุ
คลาสสาธารณะ QuickredIsclient {รหัส charset สุดท้ายคงที่ = charset.forName ("UTF-8"); แบบสแตติกส่วนตัว redistemplate <สตริงสตริง> เทมเพลต; การลงทะเบียนโมฆะสาธารณะคงที่ (redistemplate <สตริงสตริง> เทมเพลต) {QuickredIsclient.template = เทมเพลต; } โมฆะคงที่สาธารณะ nullcheck (วัตถุ ... args) {สำหรับ (object obj: args) {ถ้า (obj == null) {โยน unlegalargumentException ใหม่ ("การโต้แย้ง Redis ไม่สามารถเป็นโมฆะ!"); }}} ไบต์คงที่สาธารณะ [] tobytes (คีย์สตริง) {nullCheck (คีย์); return key.getBytes (รหัส); } ไบต์คงที่สาธารณะ [] [] tobytes (รายการ <String> ปุ่ม) {byte [] [] bytes = byte ใหม่ [keys.size ()] []; ดัชนี int = 0; สำหรับ (คีย์สตริง: คีย์) {ไบต์ [ดัชนี ++] = tobytes (คีย์); } คืนไบต์; } สตริงคงที่สาธารณะ getStr (คีย์สตริง) {return template.execute ((rediscallback <string>) con -> {byte [] val = con.get (tobytes (key)); return val == null? null: สตริงใหม่ (val);}); } โมฆะคงที่สาธารณะ putstr (คีย์สตริง, ค่าสตริง) {template.execute ((rediscallback <void>) con -> {con.set (tobytes (คีย์), tobytes (value)); return null;}); } public Static Long inc (คีย์สตริง, เพิ่มความยาว) {return template.execute ((rediscallback <lont>) con -> {record ยาว = con.incrby (tobytes (คีย์), เพิ่ม); return record == null? 0l: record;}); } public static long hincr (คีย์สตริง, ฟิลด์สตริง, เพิ่มความยาว) {return template.execute ((rediscallback <long>) con -> {record long = con.hincrby (tobytes (คีย์), tobytes (ฟิลด์), เพิ่ม); } สาธารณะคงที่ <t> t hget (คีย์สตริง, ฟิลด์สตริง, คลาส <t> clz) {return template.execute ((rediscallback <t>) con -> {byte [] records = con.hget (tobytes (key), tobytes (ฟิลด์); ถ้า (บันทึก == null) } สาธารณะคงที่ <t> แผนที่ <สตริง, t> hmget (คีย์สตริง, รายการ <string> ฟิลด์, คลาส <t> clz) {list <byte []> list = template.execute ((rediscallback <list <byte [] >>) con -> con.hmget (tobytes (คีย์) if (collectiontils.isempty (รายการ)) {return collections.empymap (); } แผนที่ <string, t> result = new hashmap <> (); สำหรับ (int i = 0; i <fields.size (); i ++) {ถ้า (list.get (i) == null) {ดำเนินการต่อ; } result.put (fields.get (i), json.parseObject (list.get (i), clz)); } ผลตอบแทนผลลัพธ์; - คลาสการกำหนดค่าที่สอดคล้องกัน
แพ็คเกจ com.git.hui.story.cache.redis; นำเข้า com.git.hui.story.cache.redis.serializer.defaultstrserializer; นำเข้า org.springframework.cache.cachemanager; org.springframework.context.annotation.configuration; นำเข้า org.springframework.context.annotation.propertysource; นำเข้า org.springframework.core.env.environment; org.springframework.data.redis.connection.redisconnectionfactory; นำเข้า org.springframework.data.redis.connection.redispassword; นำเข้า org.springframework.data.redis.connection.lettuce.lettuceconnectory; org.springframework.data.redis.core.redistemplate;/*** สร้างโดย Yihui ใน 18:45 18/6/11 */@configuration@propertySource (value = "classpath: application.yml") คลาสสาธารณะ redisconf {สภาพแวดล้อมสุดท้ายส่วนตัว; สาธารณะ 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 = ใหม่ redistemplate <> (); REDISTEMPLATE.SETCONNECTIONFACTORY (REDISCONNECTIONFACTORY); defaultStrSerializer serializer = ใหม่ defaultStrSerializer (); REDISTEMPLATE.SETVALUEIALIALIZER (Serializer); REDISTEMPLATE.SETHASHVALUEIALIALIZER (Serializer); REDISTEMPLATE.SetKeySerializer (Serializer); REDISTEMPLATE.SETHASHKEYSERIALIZER (Serializer); Redistemplate.AfterPropertiesset (); quickredisclient.register (redistemplate); ส่งคืน redistemplate; } @Bean สาธารณะ redisconnectionFactory redisconnectionFactory () {lettuceconnectionFactory fac = ใหม่ 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.afterpropertiesset (); คืน FAC; - 2. การสนับสนุนคอนโทรลเลอร์
ก่อนอื่นกำหนดพารามิเตอร์คำขอ:
@Datapublic คลาส WebCountreqdo ใช้ serializable {appkey สตริงส่วนตัว; ตัวอ้างอิงสตริงส่วนตัว}ประการที่สองคือการใช้อินเทอร์เฟซคอนโทรลเลอร์ ให้ความสนใจเล็กน้อยกับตรรกะของการนับตามเส้นทาง:
@slf4j@restcontroller@requestmapping (path = "/count") คลาสสาธารณะ WebCountController {@requestmapping (path = "cc", method = {requestmethod.get}) การตอบสนองสาธารณะ if (stringUtils.isblank (appkey)) {return responsewrapper.errorReRorNmix (status.statusenum.illegal_params_mix, "โปรดระบุ appkey!"); } string referer = reqinfocontext.getReqInfo (). getReferer (); if (stringutils.isblank (referer)) {referer = webCountreqdo.getReferer (); } if (stringUtils.isblank (referer)) {return responsewrapper.erRorReRorReRnMix (status.statusenum.fail_mix, "ไม่สามารถรับผู้ร้องขอ!"); } return responsewrapper.successreturn (doupdatecnt (appkey, referer)); } ส่วนตัว CountDto DoupDatecnt (String appkey, string referer) {ลอง {ถ้า (! referer.startswith ("http")) {referer = "https: //" + referer; } uri uri = uri ใหม่ (ผู้อ้างอิง); สตริงโฮสต์ = uri.getHost (); String Path = uri.getPath (); Long count = quickredisclient.hincr (appkey, path, 1); Long Total = quickredisclient.hincr (appkey, โฮสต์, 1); ส่งคืน countdto ใหม่ (นับรวม); } catch (exception e) {log.error ("รับข้อผิดพลาดเส้นทางอ้างอิง! ผู้อ้างอิง: {}, e: {}", ผู้อ้างอิง, e); ส่งคืน CountDTO ใหม่ (1L, 1L); -ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น