1 課程補充
1.1 網路的知識
1.1.1 虛擬機器和window的連線
說明:虛擬機器的nat模式依賴於net8網路卡,nat8網路卡的地址是一個閘道器,在window系統中.window系統訪問Linux系統必須經過nat8網路卡.否則不能通訊
1.1.2 虛擬化關閉
說明:該報錯資訊是由於計算機關閉了虛擬化設定.需要進入bios系統中開啟即可F10儲存退出.
1.1.3 資料庫連結長時間連結不上
說明:1.關閉防火牆
2.開放mysql對外的訪問許可權
3.ping 主機IP地址是否成功
4.將nat8網路卡重啟
5.安裝mysql開始
6.保證mysql資料的一致性
2 Redis
2.1 Redis介紹
2.1.1 分析
說明:資料庫中雖然實現了主從複製和讀寫分離.在一定程度上能夠抗擊高併發,但是效能並不是特別的完善.現在所面臨的主要問題是使用者大量的讀的操作所引發的高併發的問題?
如何處理:快取機制
2.1.2 快取機制
說明:快取機制是降低了客戶端訪問伺服器的訪問頻次.並且快取中的資料是與伺服器(資料庫)中的資料是同步的.
2.1.3 引入快取引發的問題
1.快取的資料如何儲存??
2.快取中的資料如何持久化??
3.快取中的資料如何實現資料同步??
4.快取中的資料記憶體如何維護
2.1.4 解決方案
1.快取中的資料可以使用Map儲存,
因為map的資料結構是key:value. key不允許重複
2.定時將快取中的資料儲存到磁碟檔案中.當伺服器當機,先應該讀取磁碟持久化檔案,恢復快取的資料.
3.當資料發生”更新”操作時,及時的維護快取的資料(攔截器/監聽器/AOP)
4.設定最大的記憶體,當記憶體超過閾值時,採用lru演算法刪除最近最少使用的資料
2.1.5 Redis介紹
說明:redis是現階段使用量較多的快取資料庫.能夠支援300000/秒集合運算.因為底層是基於c語言開發的.
2.1.6 Redis下載
2.2 安裝redis
2.2.1 引入jar包
2.2.2 編譯redis
說明:如果出現上述檔案表示編譯成功
-
redis-server 表示啟動redis
-
redis-cli 連線redis的客戶端
-
redis-check-rdb 檢測資料持久化檔案 rdb
-
redis-check-aof 檢測redis持久化檔案aof
2.2.3 安裝redis
說明:如果出現上圖的提示,表示redis安裝成功
2.2.4 Redis啟動
說明:啟動的命令 redis-server
2.2.5 開啟redis的後臺啟動
- 編輯配置檔案
vim redis.conf
- 取消IP繫結
- 關閉保護模式
4.開啟後臺啟動
- 啟動測試
redis-server redis.conf
5.關閉redis
Kill -9 9249
redis-cli shutdown
2.2.6 Redis客戶端測試
命令:redis-cli 進入客戶端
2.2.7 Redis命令
說明:學習redis命令
指令 |
說明 |
案例 |
set |
設定key的值 |
set name tom |
get |
獲取指定 key 的值 |
get name |
strlen |
獲取key值的長度 |
strlen name |
exists |
檢查給定 key 是否存在 |
exists name 返回1存在 0不存在 |
del |
刪除指定的key/key1 key2 |
del name1 name2 |
keys |
命令用於查詢所有符合給定模式 pattern 的 key |
Keys * 查詢全部的key值 Keys n?me 佔位符 Keys name* 以name開頭的key |
mset |
賦值多個key-value |
mset key1 value1 key2 value2 key3 value3 同時賦值多個值 |
mget |
獲取多個key |
Mget key1 key2 key3 |
append |
對指定的key進行追加 |
append key 123456 value123456 append key " 123456" value 123456中間多一個空格 |
Type |
檢視key的型別 |
Type key1 127.0.0.1:6379> TYPE key1string |
Flushdb |
清空當前資料庫 |
Flushdb 清空資料庫 |
Select |
切換資料庫 |
Select 0-15 redis一共有16個資料庫 |
FLUSHALL |
清空全部資料庫資料 |
flushall |
Incr |
自動增長1 |
Incr num 資料會自動加1 Incr string 資料庫會報錯 |
Decr |
自動減1 |
Decr name 資料會自動減1 |
incrby |
指定步長自增 |
Incrby 2 每次自增2 |
Decrby |
指定步長自減 |
Decrby 2每次減2 |
Expire |
指定key的失效時間單位是秒(s) |
EXPIRE name1 5 5秒後資料失效 |
Ttl |
檢視key的剩餘存活時間 |
Ttl name -2表示失效 -1沒有失效時間 |
Pexpire |
設定失效時間(毫秒) |
Pexpire name 1000 用於秒殺業務 |
Persist |
撤銷失效時間 |
撤銷失效時間 |
2.3 Redis入門案例
2.3.1 引入jar包檔案
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.4.1.RELEASE</version> </dependency> <jedis.version>2.6.2</jedis.version> <!-- jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>${jedis.version}</version> </dependency>
2.3.2 入門案例
/** * 1.連線遠端redis的客戶端 ip:6379 * 2.通過jedis運算元據的增和刪 */ @Test public void test01(){ Jedis jedis = new Jedis("192.168.126.142", 6379); jedis.set("name", "jerry"); System.out.println("獲取redis中的資料:"+jedis.get("name")); }
2.4 Spring管理jedis
2.4.1 編輯配置檔案
<!--Spring管理Jedis name= "構造引數的名稱" index="構造引數的位置" 總結:構造注入時使用index不用name.原因由於java只會維護形參的資料型別 不會維護形參的名稱.所有通過name屬性進行構造注入時,可能會產生風險. 所以建議使用index. addUser(int age,String sex) addUser(int arg0,String arg1) 由於沒有匯入原始碼 關於type型別的說明: 一般情況下,SPring會自動的維護引數型別,所以可以省略不寫. 但是如果類中的構造方法過載較多,出現引數個數相同的情況, 需要指定引數型別.Spring根據特定的引數實現構造注入. --> <bean id="jedis" class="redis.clients.jedis.Jedis"> <constructor-arg index="0" value="${redis.host}" type="java.lang.String"/> <constructor-arg index="1" value="${redis.port}" type="int"/> </bean>
2.4.2 引入redis的配置檔案
1.編輯redis.properties
2.交給Spring容器管理
2.5 Redis快取例項
2.5.1 使用快取的要求
說明:將變化不大的資料新增到快取中.
省市縣區,部門名稱/資訊/商品的分類目錄
2.5.2 商品分類目錄實現快取
說明:商品分類目錄使用redis快取實現
規定:
- key值使用parentId
- value值使用List集合的JSON串
步驟:
1.當使用者查詢資料時,先查詢快取
2.當快取中沒有資料,應該查詢後臺的資料庫
3.將查詢的結果轉化為JSON串,存入redis中
4.當使用者再次查詢時,快取中已經含有該資料
5.將redis中的JSON串轉化為List集合
6.將list集合返回
2.5.3 編輯Controller
2.5.4 編輯Service
/** * 1.當使用者查詢資料時,先查詢快取 2.當快取中沒有資料,應該查詢後臺的資料庫 3.將查詢的結果轉化為JSON串,存入redis中 4.當使用者再次查詢時,快取中已經含有該資料 5.將redis中的JSON串轉化為List集合 6.將list集合返回 */ @Override public List<ItemCat> findItemCatByParentId(Long parentId) { //建立List集合 List<ItemCat> itemCatList = new ArrayList<ItemCat>(); //定義key 定義字首保證key不重複 String key = "ITEM_CAT_"+parentId; //從快取中獲取資料 String jsonData = jedis.get(key); try { //判斷返回值是否為空 if(StringUtils.isEmpty(jsonData)){ //表示沒有快取 查詢資料庫 ItemCat itemCat = new ItemCat(); itemCat.setParentId(parentId); itemCat.setStatus(1); //正常的分類資訊 itemCatList = itemCatMapper.select(itemCat); //將itemcatList集合轉化為JSON串 String resultJSON = objectMapper.writeValueAsString(itemCatList); //將資料存入redis快取中 jedis.set(key, resultJSON); }else{ //表示redis中含有資料,將JSON資料轉化為List集合 ItemCat[] itemCats = objectMapper.readValue(jsonData,ItemCat[].class); //將返回值轉化為List集合 itemCatList = Arrays.asList(itemCats); } } catch (Exception e) { e.printStackTrace(); } return itemCatList; }
2.5.5 編輯pojo
說明:如果不新增上述的註解則會報錯
說明:由於將JSON資料轉化為物件時,需要呼叫其中的setXXX()方法.但是state和text屬性是樹形結構展現資料時的要求和實際的業務沒有關係.所以新增@JsonIgnoreProperties(ignoreUnknown=true)表示忽略未知欄位.最終實現物件的轉化.
2.5.6 速度測試
- 使用redis快取前
沒有使用redis快取前耗時400毫秒
- 使用redis快取後
速度明顯提升
2.5.7 修改
1.修改資料檔案
2.修改nginx配置檔案
2.6 Redis單臺高階編輯
2.6.1 定義配置檔案
<!--通過執行緒池的方式整合單臺redis --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <!--定義連線的總數 --> <property name="maxTotal" value="${redis.maxTotal}"/> <!--定義最大的空閒數量 --> <property name="maxIdle" value="${redis.maxIdle}"/> <!--定義最小空閒數量 --> <property name="minIdle" value="${redis.minIdle}"></property> </bean> <!--通過工廠模式建立jedis連線 需要指定 host主機 和埠號 引用連線池配置 --> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="${redis.host}"/> <property name="port" value="${redis.port}"/> <!--引入執行緒池的配置 --> <property name="poolConfig" ref="poolConfig"/> </bean> <!--配置SpringJedisTemplate spring操作redis的模板工具API --> <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"> <!--配置redis工廠 --> <property name="connectionFactory" ref="jedisConnectionFactory"></property> </bean>
2.6.2 引入redis.properties檔案
redis.host=192.168.126.142
redis.port=6379
redis.maxTotal=1000
redis.maxIdle=30
redis.minIdle=10
2.6.3 編輯工具類
@Service public class RedisService { @Autowired //注入spring的模板工具 private StringRedisTemplate redisTemplate; public void set(String key,String value){ ValueOperations<String, String> operations = redisTemplate.opsForValue(); //將資料寫入redis中 operations.set(key, value); } //通過key獲取資料 public String get(String key){ ValueOperations<String, String> operations = redisTemplate.opsForValue(); return operations.get(key); } }
說明:將jt-common編輯完成之後需要重新進行打包,否則業務層呼叫不生效
2.6.4 編輯service
說明:將原有單個jedis的操作改為jedis連線池的形式.效能更好,更加適用於企業開發.