1. 程式人生 > 實用技巧 >內網滲透常用命令

內網滲透常用命令

一、快取雪崩

快取雪崩:
redis掛掉了,請求全部走資料庫
對快取資料設定了相同的過期時間,導致快取有段時間失效,請求全部走資料庫
快取雪崩,請求全部走資料庫,資料庫會掛掉,這樣可能造成整個伺服器坍塌
解決方案:

  1. 針對“對快取資料設定了相同的過期時間,請求全部走資料庫”
    在快取的時候給過期時間設定一個隨機值,這樣就會大幅的減少快取過期時間在同一時間
  2. 分事發前、事發中、事發後的解決
    事發前: 實現redis的高可用(利用redis cluster叢集 或 主從+哨兵),減少redis掛掉
    事發中: 萬一redis真的掛掉了,可以設定本地快取(ehcache)+限流(hystrix),儘量避免我們資料庫掛掉
    事發後:redis的持久化,重啟redis後自動從磁碟上讀取數,快速恢復快取資料

二、快取穿透

快取穿透:
不停的訪問一個數據庫根本沒有的資料,比如黑客在攻擊資料庫時會請求ID為負值的,但是資料庫中不存在的資料時不會存到快取中,這樣就會導致資料庫崩潰,服務宕機
解決方案:

  1. 當資料庫查詢沒有資料時,將空物件設定到快取中,並給此物件設定一個過期時間
  2. 在請求redis之前就做攔截,非法資料的攔截、過濾

三、快取擊穿

快取擊穿:
某個 key 非常熱點,訪問非常頻繁,處於集中式高併發訪問的情況,當這個 key 在失效的瞬間,大量的請求就擊穿了快取,直接請求資料庫,就像是在一道屏障上鑿開了一個洞
解決方案

  1. 將熱點資料設定為永不過期
  2. 使用redis或者zookeeper的互斥鎖,等一個請求構建萬快取之後再釋放鎖,進而其他請求才能訪問此key( 一般使用此種方法來解決)

四、程式碼實現

1、防止快取穿透原始碼實現

(1)使用的是Google的Bloom Filter
     <1>引入依賴
       <dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
		</dependency>
(2)使用雙重驗證鎖解決高併發環境下的快取穿透問題
@Service
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentMapper studentMapper;
    //springboot自動配置的,直接注入到類中即可使用
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    /**
     * 查詢所有學生資訊,帶有快取
     * @return
     */
    public List<Student> getAllStudent() {
        //在高併發條件下,會出現快取穿透
        List<Student> studentList = (List<Student>)redisTemplate.opsForValue().get("allStudent");
        if (null == studentList) {
            //5個人, 4個等,1個進入
            synchronized (this) {
    //雙重檢測鎖,假使同時有5個請求進入了上一個if(null == studentList),
    //加了鎖之後one by one 的訪問,這裡再次對快取進行檢測,盡一切可能防止快取穿透的產生,但是效能會有所損失
                studentList = (List<Student>)redisTemplate.opsForValue().get("allStudent");
                if (null == studentList) {
                    studentList = studentMapper.getAllStudent();
                    redisTemplate.opsForValue().set("allStudent", studentList);System.out.println("請求的資料庫。。。。。。");} else {//System.out.println("請求的快取。。。。。。");
                }}} else {System.out.println("請求的快取。。。。。。");
        }return studentList;}}	

2、防止快取雪崩、快取擊穿原始碼實現

(1)加互斥鎖,互斥鎖參考程式碼如下:
 static Lock reenLock = new ReentrantLock();
   public List<String> getData04() throws InterruptedException {
       List<String> result = new ArrayList<String>();
       // 從快取讀取資料
       result = getDataFromCache();
       if (result.isEmpty()) {
           if (reenLock.tryLock()) {
               try {
                System.out.println("我拿到鎖了,從DB獲取資料庫後寫入快取");
                   // 從資料庫查詢資料
                   result = getDataFromDB();
                   // 將查詢到的資料寫入快取
                   setDataToCache(result);
               } finally {
                   reenLock.unlock();// 釋放鎖
               }
           } else {
               result = getDataFromCache();// 先查一下快取
               if (result.isEmpty()) {
                 System.out.println("我沒拿到鎖,快取也沒資料,先小憩一下");
                   Thread.sleep(100);// 小憩一會兒
                   return getData04();// 重試
               }
           }
       }
       return result;
   }

3、快取穿透、雪崩、擊穿最終結果都是對資料庫造成壓力
(1)不管是使用雙重檢索還是加互斥鎖,都是為了減輕DB壓力
(2)一般情況下使用加互斥鎖來實現