戴著口罩無法顏面辨識 傳蘋果將在新機合併Face ID與Toch ID_租車

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

有別於一般網頁架設公司,除了模組化的架站軟體,我們的營業主軸還包含:資料庫程式開發、網站建置、網頁設計、電子商務專案開發、系統整合、APP設計建置、專業網路行銷。

由於武漢肺炎肆虐的關係,口罩基本上已經變成生活的標準配備,許多人出門就是把口罩戴的緊緊的。雖然在健康上提升了不少安全,但是對於那些仰賴顏面辨識的手機來講,就添增不少困擾,不少人要解鎖手機的時候,都還得拉下口罩,著實有點不方便。而近日傳出,蘋果官方似乎打算在新一代的iPhone中,將原本的Touch ID與Face ID做個合併,讓大家可以更輕鬆的幫手機解鎖。

↑口罩的佩戴,真的造成許多顏面辨識功能無法使用。(示意圖/pixabay)

根據《9to5mac》報導指出,其實蘋果對於合併Touch ID與Face ID這事情,已經計畫了好幾年。但由於螢幕限制的關係,這個想法一直沒辦法付諸實行。而在1月中旬時,《彭博社》報導指出,蘋果目前正在開發「螢幕指紋辨識器」,似乎是有意思將Toch ID重新回歸市場。而在報導中指出,這款具備Touch ID與Face ID的iPhone即將上市。

 

再根據《華爾街日報》報導指出,有兩名蘋果的前員工表示,蘋果內部一直在進行螢幕指紋辨識器的研究,並且明確的考慮在一個設備上「同時安裝Touch ID與Face ID」。

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

日本、大陸,發現這些先進的國家已經早就讓電動車優先上路,而且先進國家空氣品質相當好,電動車節能減碳可以減少空污

 

《9to5mac》認為,在今年的iPhone新機上,應該不用太過期待會有亮眼的新功能,所以像是「Touch ID與Face ID」這樣同步合併的新功能,會變成一個不錯的選項,尤其武漢肺炎看樣子在今年應該無法歇息,所以這樣的功能應該也會受到使用者的歡迎。同時,《9to5mac》表示,今年的iPhone有可能會移除Lightning插孔,變成使用USB Type-C來取代。

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

※超省錢租車方案

商務出差、學生出遊、旅遊渡假、臨時用車!GO 神州租賃有限公司!合法經營、合法連鎖、合法租賃小客車!

從源碼研究如何不重啟Springboot項目實現redis配置動態切換_包裝設計

※產品缺大量曝光嗎?你需要的是一流包裝設計!

窩窩觸角包含自媒體、自有平台及其他國家營銷業務等,多角化經營並具有國際觀的永續理念。

上一篇Websocket的續篇暫時還沒有動手寫,這篇算是插播吧。今天講講不重啟項目動態切換redis服務。

背景

多個項目或微服務場景下,各個項目都需要配置redis數據源。但是,每當運維搞事時(修改redis服務地址或端口),各個項目都需要進行重啟才能連接上最新的redis配置。服務一多,修改各個項目配置然後重啟項目就非常蛋疼。所以我們想要找到一個可行的解決方案,能夠不重啟項目的情況下,修改配置,動態切換redis服務。

如何實現切換redis連接

剛遇到這個問題的時候,想必如果對spring-boot-starter-data-redis不是很熟悉的人,首先想到的就是去百度一下(安慰下自己:不要重複造輪子嘛)。

可是一陣百度之後,你找到的結果可能都是這樣的:

public ValueOperations updateRedisConfig() {
    JedisConnectionFactory jedisConnectionFactory = (JedisConnectionFactory) stringRedisTemplate.getConnectionFactory();
    jedisConnectionFactory.setDatabase(db);
    stringRedisTemplate.setConnectionFactory(jedisConnectionFactory);
    ValueOperations valueOperations = stringRedisTemplate.opsForValue();
    return ValueOperations;

沒錯,絕大多數都是切換redis db的代碼,而沒有切redis服務地址或賬號密碼的。而且天下代碼一大抄,大多數博客都是一樣的內容,這就讓人很噁心。

沒辦法,網上沒有,只能自己造輪子了。不過,從強哥這種懶人思維來說,上面的代碼既然能切庫,那是不是host、username、password也同樣可以,於是我們加入如下代碼:

public ValueOperations updateRedisConfig() {
    JedisConnectionFactory jedisConnectionFactory = (JedisConnectionFactory) stringRedisTemplate.getConnectionFactory();
    jedisConnectionFactory.setDatabase(db);
    jedisConnectionFactory.setHostName(host);
    jedisConnectionFactory.setPort(port);
    jedisConnectionFactory.setPassword(password);
    stringRedisTemplate.setConnectionFactory(jedisConnectionFactory);
    ValueOperations valueOperations = stringRedisTemplate.opsForValue();
    return valueOperations;
}

話不多說,改完重啟一下。額,運行結果並沒有讓我們見證奇迹的時刻。在調用updateRedisConfig方法的之後,使用redisTemplate還是只能切換db,不能進行服務地址或賬號密碼的更新。

這就讓人頭疼了,不過想也沒錯,如果可以的話,網上不應該找不到類似的代碼。那麼,現在該咋辦嘞?

強哥的想法是:redisTemplate每次獲取ValueOperations執行get/set方法的時候,都會去連接redis服務器,那麼我們就從這兩個方法入手看看能不能找得到解決方案。

接下來就是源碼研究的過程啦,有耐心的小夥伴就跟着強哥一起找,只想要結果的就跳到文末吧~

首先來看看入手工具方法set:

 
public boolean set(final String key, Object value) {
  boolean result = false;
  try {
          ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
          operations.set(key, value);
          result = true;
      } catch (Exception e) {
          logger.error("set cache error:", e);
      }
  return result;
}

我們進入到operations.set(key, value);的set方法實現:

public boolean set(String key, Object value) {
        boolean result = false;
    try {
        ValueOperations<Serializable, Object> operations = this.redisTemplate.opsForValue();
        operations.set(key, value);
        result = true;
    } catch (Exception var5) {
      this.logger.error("set error:", var5);
    }
    return result;
}

哦,走的是execute方法,進去看看,具體調用的是AbstractOperations的RedisTemplate的execute方法(中間跳過幾個重載方法跳轉):

public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) {
    Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it");
    Assert.notNull(action, "Callback object must not be null");
    RedisConnectionFactory factory = getConnectionFactory();
    RedisConnection conn = null;
    try {
      if (enableTransactionSupport) {
// only bind resources in case of potential transaction synchronization
        conn = RedisConnectionUtils.bindConnection(factory, enableTransactionSupport);
      } else {
        conn = RedisConnectionUtils.getConnection(factory);
      }
      boolean existingConnection = TransactionSynchronizationManager.hasResource(factory);
      RedisConnection connToUse = preProcessConnection(conn, existingConnection);
      boolean pipelineStatus = connToUse.isPipelined();
      if (pipeline && !pipelineStatus) {
        connToUse.openPipeline();
      }
      RedisConnection connToExpose = (exposeConnection ? connToUse : createRedisConnectionProxy(connToUse));
      T result = action.doInRedis(connToExpose);
      // close pipeline
      if (pipeline && !pipelineStatus) {
        connToUse.closePipeline();
      }
      // TODO: any other connection processing?
      return postProcessResult(result, connToUse, existingConnection);
    } finally {
      RedisConnectionUtils.releaseConnection(conn, factory);
    }
}

方法內容很長,不過大致可以看出前面是獲取一個RedisConnection對象,後面應該就是命令的執行,為什麼說應該?因為強哥也沒去細看後面的實現,因為我們要關注的就是怎麼拿到這個RedisConnection對象的。

那麼我們走RedisConnectionUtils.getConnection(factory);這句代碼進去看看,為什麼我知道是走這句而不是上面那句,因為強哥沒開事務,如果大家有打斷點,應該默認也是走的這句,跳到具體的實現方法:RedisConnectionUtils.doGetConnection(……):

public static RedisConnection doGetConnection(RedisConnectionFactory factory, boolean allowCreate, boolean bind,
boolean enableTransactionSupport) {
    Assert.notNull(factory, "No RedisConnectionFactory specified");
    RedisConnectionHolder connHolder = (RedisConnectionHolder) TransactionSynchronizationManager.getResource(factory);
    if (connHolder != null) {
      if (enableTransactionSupport) {
        potentiallyRegisterTransactionSynchronisation(connHolder, factory);
      }
      return connHolder.getConnection();
    }
    if (!allowCreate) {
      throw new IllegalArgumentException("No connection found and allowCreate = false");
    }
    if (log.isDebugEnabled()) {
      log.debug("Opening RedisConnection");
    }
    RedisConnection conn = factory.getConnection();
    if (bind) {
      RedisConnection connectionToBind = conn;
      if (enableTransactionSupport && isActualNonReadonlyTransactionActive()) {
        connectionToBind = createConnectionProxy(conn, factory);
      }
      connHolder = new RedisConnectionHolder(connectionToBind);
      TransactionSynchronizationManager.bindResource(factory, connHolder);
      if (enableTransactionSupport) {
        potentiallyRegisterTransactionSynchronisation(connHolder, factory);
      }
      return connHolder.getConnection();
    }
    return conn;
  }

代碼還是很長,話不多說,斷點走的這句:RedisConnection conn = factory.getConnection();那就看看其實現方法吧:JedisConnectionFactory.getConnection(),這個是個關鍵方法:

public RedisConnection getConnection() {
 if (cluster != null) {
   return getClusterConnection();
 }
 Jedis jedis = fetchJedisConnector();
 JedisConnection connection = (usePool ? new JedisConnection(jedis, pool, dbIndex, clientName)
     : new JedisConnection(jedis, null, dbIndex, clientName));
 connection.setConvertPipelineAndTxResults(convertPipelineAndTxResults);
 return postProcessConnection(connection);
}

看到了,代碼很短,但是我們從中可以獲取到的內容卻很多:

第一個判斷是是否有集群,這個強哥項目暫時沒用,所以不管;如果大家有用到,可能要要考慮下裏面的代碼。

Jedis對象是在這裏創建的,熟悉redis的應該都知道:Jedis是Redis官方推薦的Java連接開發工具。直接用它就能執行redis命令。

usePool 這個變量,說明我們連接的redis服務器的時候可能用到了連接池;不知道大家看到usePool會不會有種恍然醒悟的感覺,很可能就是因為我們使用了連接池,所以即使我們之前的代碼中切換了賬號密碼,連接池的連接還是沒有更新導致的處理無效。

我們先看看fetchJedisConnector方法實現:

protected Jedis fetchJedisConnector() {
  try {
    if (usePool && pool != null) {
      return pool.getResource();
    }
 
    Jedis jedis = new Jedis(getShardInfo());
  // force initialization (see Jedis issue #82)
    jedis.connect();
  
    potentiallySetClientName(jedis);
    return jedis;
  } catch (Exception ex) {
throw new RedisConnectionFailureException("Cannot get Jedis connection", ex);
  }
}

哦,可以看到,Jedis對象是根據getShardInfo()構建出來的:

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網動廣告出品的網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上她。

public BinaryJedis(JedisShardInfo shardInfo) {
  this.client = new Client(shardInfo.getHost(), shardInfo.getPort(), shardInfo.getSsl(), shardInfo.getSslSocketFactory(), shardInfo.getSslParameters(), shardInfo.getHostnameVerifier());
  this.client.setConnectionTimeout(shardInfo.getConnectionTimeout());
  this.client.setSoTimeout(shardInfo.getSoTimeout());
  this.client.setPassword(shardInfo.getPassword());
  this.client.setDb((long)shardInfo.getDb());
}

那就是說,只要我們掌握了這個JedisShardInfo的由來,我們就可以實現redis相關配置的切換。而這個getShardInfo()方法就是返回了JedisConnetcionFactory類的JedisShardInfo shardInfo屬性:

public JedisShardInfo getShardInfo() {
  return shardInfo;
}

那麼如果我們知道了這個shardInfo是如何創建的,是不是就可以干預到RedisConnect的創建了呢?我們來找找它被創建的地方:

走的JedisConnectionFactory的afterPropertiesSet()進去看看:

/*
  * (non-Javadoc)
  * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
  */
public void afterPropertiesSet() {
 if (shardInfo == null) {
   shardInfo = new JedisShardInfo(hostName, port);
   if (StringUtils.hasLength(password)) {
     shardInfo.setPassword(password);
   }  
   if (timeout > 0) {
       setTimeoutOn(shardInfo, timeout);
     }
   }

   if (usePool && clusterConfig == null) {
     this.pool = createPool();
   }
 
   if (clusterConfig != null) {
     this.cluster = createCluster();
   }
}

哦吼~,整篇博文最關鍵的代碼終於出現了。我們可以看到,JedisShardInfo的所有信息都是從JedisConnetionFactory的屬性中來的,包括hostName、port、password、timeout等。而且,如果JedisShardInfo為null時,調用afterPropertiesSet方法會幫我們創建出來。然後,該方法還會幫我們創建新的連接池,簡直完美。最最重要的是,這個方法是public的。

所以,嘿嘿,綜上,我們總結改造的幾個點:

1.連接redis用到了連接池,需要先給他銷毀;

2.創建Jedis的時候,將JedisShardInfo先設為null;

3.手動設置JedisConnetionFactory的hostName、port、password等信息;

4.調用JedisConnetionFactory的afterPropertiesSet方法創建JedisShardInfo;

5.給RedisTemplate設置處理后的JedisConnetionFactory,這樣在下次使用set或get方法的時候就會去創建新改配置的連接池啦。

實現如下:

public void updateRedisConfig() {
  RedisTemplate template = (RedisTemplate) applicationContext.getBean("redisTemplate");
  JedisConnectionFactory redisConnectionFactory = (JedisConnectionFactory) template.getConnectionFactory();
//關閉連接池
  redisConnectionFactory.destroy();
  redisConnectionFactory.setShardInfo(null);
  redisConnectionFactory.setHostName(host);
  redisConnectionFactory.setPort(port);
  redisConnectionFactory.setPassword(password);
  redisConnectionFactory.setDatabase(database);
  //重新創建連接池
  redisConnectionFactory.afterPropertiesSet();
  template.setConnectionFactory(redisConnectionFactory);
}

重啟項目之後,調用這個方法,就可以實現redis庫及服務地址、賬號密碼的切換而無需重啟項目了。

如何實現動態切換

強哥這裏就使用同一配置中心Apollo來進行動態配置的。

首先不懂Apollo是什麼的同學,先Apollo官網半日游吧(直接看官網教程,比看其他博客強)。簡單的說就是一個統一配置中心,將原來配置在項目本地的配置(如:Spring中的application.properties)遷移到Apollo上,實現統一的管理。

使用Apollo的原因,其實就是因為其接入簡單,且具有實時更新回調的功能,我們可以監聽Apollo上的配置修改,實現針對修改的配置內容進行相應的回調監聽處理。

因此我們可以將redis的配置信息配置在Apollo上,然後監聽這些配置。當Apollo上的這些配置修改時,我們在ConfigChangeListener中,調用上面的updateRedisConfig方法就可以實現redis配置的動態切換了。

接入Apollo代碼非常簡單:

Config redisConfig = ConfigService.getConfig("redis");
ConfigChangeListener listener = this::updateRedisConfig;
redisConfig.addChangeListener(listener);

這樣,我們就可以實現具體所謂的動態更新配置啦~

當然,其他有相同功能的配置中心其實也可以,只是強哥項目中暫時用的就是Apollo就拿Apollo來講了。

考慮到篇幅已經很長了,就不多解釋Apollo的使用了,用過的自然看得懂上面的方法,有不懂的也可以留言提問哦。

好了,就到這吧,原創不易,怎麼支持你們知道,那麼下次見啦

關注公眾號獲取更多內容,有問題也可在公眾號提問哦:

強哥叨逼叨

叨逼叨編程、互聯網的見解和新鮮事

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

上新台中搬家公司提供您一套專業有效率且人性化的辦公室搬遷、公司行號搬家及工廠遷廠的搬家服務

小米11 國際版將於2/8 晚間發表,有望 3 月在台亮相_潭子電動車

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

有別於一般網頁架設公司,除了模組化的架站軟體,我們的營業主軸還包含:資料庫程式開發、網站建置、網頁設計、電子商務專案開發、系統整合、APP設計建置、專業網路行銷。

在 2020 年 12 月底,小米於中國發表首款搭載高通 Snapdragon 888 處理器的旗艦手機「小米11」,截至目前小米11 也只在中國當地銷售。針對中國以外的市場方面,小米11 國際版除了日前通過 NCC 認證,近期也正式宣佈將於 2 月 8 日晚上 8 點舉行小米11 國際版發表會,未來小米11 也將引進台灣市場販售。

小米11 國際版將於2/8 晚間發表,有望 3 月在台亮相

小米11 國際版多數規格預計和去年底發表的中國版的關鍵關格大致相似,像是搭載 Qualcomm Snapdragon 888 處理器、 6.81 吋 2K(3200×1440 WQHD)E4 材質 AMOLED 四曲面柔性螢幕。
螢幕支持最高 120Hz 螢幕更新率、480Hz 觸控採樣率, 1500nit 峰值亮度、480Hz  觸控採樣率、5,000,000:1 對比度,螢幕也擁有 100% P3 色域和 HDR10+ 認證。
另外,小米11 螢幕玻璃採用康寧 Gorilla Glass Victus 玻璃保護,抗摔性相較前代提升 1.5倍、耐刮性能提升 2 倍。

相機方面,小米 11 採用 1 億 800 萬像素三鏡頭主相機設計,分別為 1 億 800 萬像素像素(1 / 1.33″超大感光元件)標準鏡頭、1300 萬像素 123° 超廣角鏡頭、 500 萬像素 50mm 微距長焦鏡頭,前置鏡頭則配備 2000 萬像素自拍相機。
此外,小米11 內建等效 4600mAh 大電池,支持 55W 有線閃充、50W 無線閃充以及10W 反向無線充電, 55W 有線閃充可在 45 分鐘充滿 100% 電量、50W 無線閃充可在 53 分鐘充滿 100% 電量。

▲圖片來源:小米(中國)

與小米11 中國版最大的差異在於小米11 國際版將加入 GMS 支援,不過目前還無法得知將推出哪幾款配色與容量選擇。雖然,小米11 國際版在下週 2 月 8 日晚上 8 點就會發表,不過台灣市場預計最快要等到 3 月才會引進銷售。

小米11 國際版線上發表會(2021/2/8 20:00開始)

 

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

日本、大陸,發現這些先進的國家已經早就讓電動車優先上路,而且先進國家空氣品質相當好,電動車節能減碳可以減少空污

延伸閱讀:
多款旗艦手機電力續航能力實測,三星 Galaxy S21 Ultra 仍敗給 iPhone 12 Pro Max

小米隔空充電技術正式發表:手持也能隔空充電,「真」無線充電時代來臨!

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

※超省錢租車方案

商務出差、學生出遊、旅遊渡假、臨時用車!GO 神州租賃有限公司!合法經營、合法連鎖、合法租賃小客車!

02 . Tomcat集群會話共享

redis簡介

redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set –有序集合)和hash(哈希類型)。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現master-slave(主從)同步。

Redis詳細請看我專門寫的redis

https://www.cnblogs.com/you-men/tag/Redis/

如何保持session會話

目前,為了使web能適應大規模的訪問,需要實現應用的集群部署。集群最有效的方案就是負載均衡,而實現負載均衡用戶每一個請求都有可能被分配到不固定的服務器上,這樣我們首先要解決session的統一來保證無論用戶的請求被轉發到哪個服務器上都能保證用戶的正常使用,即需要實現session的共享機制。

在集群系統下實現session統一的有如下幾種方案:

1、請求精確定位:sessionsticky,例如基於訪問ip的hash策略,即當前用戶的請求都集中定位到一台服務器中,這樣單台服務器保存了用戶的session登錄信息,如果宕機,則等同於單點部署,會丟失,會話不複製。

2、session複製共享:sessionreplication,如tomcat自帶session共享,主要是指集群環境下,多台應用服務器之間同步session,使session保持一致,對外透明。 如果其中一台服務器發生故障,根據負載均衡的原理,調度器會遍歷尋找可用節點,分發請求,由於session已同步,故能保證用戶的session信息不會丟失,會話複製,。

此方案的不足之處:

必須在同一種中間件之間完成(如:tomcat-tomcat之間).

session複製帶來的性能損失會快速增加.特別是當session中保存了較大的對象,而且對象變化較快時, 性能下降更加顯著,會消耗系統性能。這種特性使得web應用的水平擴展受到了限制。

Session內容通過廣播同步給成員,會造成網絡流量瓶頸,即便是內網瓶頸。在大併發下錶現並不好

3、基於cache DB緩存的session共享

基於memcache/redis緩存的 session 共享

即使用cacheDB存取session信息,應用服務器接受新請求將session信息保存在cache DB中,當應用服務器發生故障時,調度器會遍歷尋找可用節點,分發請求,當應用服務器發現session不在本機內存時,則去cache DB中查找,如果找到則複製到本機,這樣實現session共享和高可用。

nginx+tomcat+redis實現負載均衡、session共享

環境
主機 操作系統 IP地址 硬件/網絡
Nginx CentOS7.3 39.108.140.0 1C2G / 公有雲
Tomcat-1 CentOS7.3 121.36.43.2 1C2G / 公有雲
Tomcat-2 CentOS7.3 49.233.69.195 1C2G / 公有雲
Redis CentOS7.3 116.196.83.113 1C2G / 公有雲
MySQL CentOS7.3 116.196.83.113 1C2G / 公有雲
實驗拓撲

在這個圖中,nginx做為反向代理,實現靜動分離,將客戶動態請求根據權重隨機分配給兩台tomcat服務器,redis做為兩台tomcat的共享session數據服務器,mysql做為兩台tomcat的後端數據庫。

nginx安裝配置

使用Nginx作為Tomcat的負載平衡器,Tomcat的會話Session數據存儲在Redis,能夠實現零宕機的7×24效果。因為將會話存儲在Redis中,因此Nginx就不必配置成stick粘貼某個Tomcat方式,這樣才能真正實現後台多個Tomcat負載平衡。

部署nginx

#!/usr/bin/env bash
# Author: ZhouJian
# Mail: 18621048481@163.com
# Time: 2019-9-3
# Describe: CentOS 7 Install Nginx Source Code Script

version="nginx-1.14.2.tar.gz"
user="nginx"
nginx=${version%.tar*}
path=/usr/local/src/$nginx
echo $path
if ! ping -c2 www.baidu.com &>/dev/null
then
	echo "網絡不通,無法安裝"
	exit
fi

yum install -y gcc gcc-c++ openssl-devel pcre-devel make zlib-devel wget psmisc
if [ ! -e $version ];then
	wget http://nginx.org/download/$version
fi
if ! id $user &>/dev/null
then
	useradd $user -M -s /sbin/nologin
fi

if [ ! -d /var/tmp/nginx ];then
	mkdir -p /var/tmp/nginx/{client,proxy,fastcgi,uwsgi,scgi}
fi
tar xf $version -C /usr/local/src
cd $path
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_flv_module \
--with-http_stub_status_module \
--with-http_sub_module \
--with-http_gzip_static_module \
--with-http_auth_request_module \
--with-http_random_index_module \
--with-http_realip_module \
--http-client-body-temp-path=/var/tmp/nginx/client \
--http-proxy-temp-path=/var/tmp/nginx/proxy \
--http-fastcgi-temp-path=/var/tmp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \
--http-scgi-temp-path=/var/tmp/nginx/scgi \
--with-pcre \
--with-file-aio \
--with-http_secure_link_module && make && make install
if [ $? -ne 0 ];then
	echo "nginx未安裝成功"
	exit
fi

killall nginx
/usr/local/nginx/sbin/nginx
#echo "/usr/local/nginx/sbin/nginx" >> /etc/rc.local
#chmod +x /etc/rc.local
#systemctl start rc-local
#systemctl enable rc-local
ss -antp |grep nginx

配置nginx反向代理:反向代理+負載均衡+健康探測,nginx.conf文件內容:

vim /usr/local/nginx/conf/nginx.conf
worker_processes  4;
events {
        worker_connections  1024;
}
    http {
        include       mime.types;
        default_type  application/octet-stream;
        sendfile        on;
        keepalive_timeout  65;
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_x_forwarded_for"';

    #blog lb by oldboy at 201303
        upstream backend_tomcat {
        #ip_hash;
        server 192.168.6.241:8080   weight=1 max_fails=2 fail_timeout=10s;
        server 192.168.6.242:8080   weight=1 max_fails=2 fail_timeout=10s;
        #server 192.168.6.243:8080   weight=1 max_fails=2 fail_timeout=10s;
        }

        server {
            listen       80;
            server_name  www.98yz.cn;
            charset utf-8;
            location / {
                root html;
                index  index.jsp index.html index.htm;
                    }
            location ~* \.(jsp|do)$ {
            proxy_pass  http://backend_tomcat;
            proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
                }
        }

    }
安裝部署tomcat應用程序服務器

在tomcat-1和tomcat-2節點上安裝JDK

在安裝tomcat之前必須先安裝JDK,JDK的全稱是java development kit,是sun公司免費提供的java語言的軟件開發工具包,其中包含java虛擬機(JVM),編寫好的java源程序經過編譯可形成java字節碼,只要安裝了JDK,就可以利用JVM解釋這些字節碼文件,從而保證了java的跨平台性。

安裝JDK,Tomcat 程序

tar xvf jdk-8u151-linux-x64.tar.gz -C /usr/local/
wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.55/bin/apache-tomcat-8.5.55.tar.gz
tar xf apache-tomcat-8.5.55.tar.gz -C /usr/local/
cd /usr/local/
mv apache-tomcat-8.5.55/ tomcat
mv jdk1.8.0_151/ jdk

按照相同方法在tomcat-2也安裝

vim conf/server.xml

// 設置默認虛擬主機,並增加jvmRoute
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat-1">
  
// 修改默認虛擬主機,並將網站文件路徑指向/web/webapp1,在host段增加context段  
<Host name="localhost"  appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Context docBase="/web/webapp1" path="" reloadable="true"/>
</Host>
  
  
// 增加文檔目錄與測試文件  
mkdir -p /web/webapp1
cd /web/webapp1
cat index.jsp 
<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
    <head>
        <title>tomcat-1</title>
    </head>
    <body>
        <h1><font color="red">Session serviced by tomcat</font></h1>
        <table aligh="center" border="1">
        <tr>
            <td>Session ID</td>
            <td><%=session.getId() %></td>
                <% session.setAttribute("abc","abc");%>
            </tr>
            <tr>
            <td>Created on</td>
            <td><%= session.getCreationTime() %></td>
            </tr>
        </table>
    tomcat-1
    </body>
<html>  
  
  
// 接下來我們將tomcat和nginx都啟動起來,可以發現用戶訪問index.jsp會一會跳轉tomcat1,一會tomcat2,session還不一致  

Tomcat-2節點與tomcat-1節點配置基本類似,只是jvmRoute不同,另外為了區分由哪個節點提供訪問,測試頁標題也不同(生產環境兩個tomcat服務器提供的網頁內容是相同的)。其他的配置都相同。

用瀏覽器訪問nginx主機,驗證負載均衡

驗證健康檢查的方法可以關掉一台tomcat主機,用客戶端瀏覽器測試訪問。

從上面的結果能看出兩次訪問,nginx把訪問請求分別分發給了後端的tomcat-1和tomcat-2,客戶端的訪問請求實現了負載均衡,但sessionid並一樣。所以,到這裏我們準備工作就全部完成了,下面我們來配置tomcat通過redis實現會話保持。

安裝redis
yum -y install gcc
wget http://download.redis.io/releases/redis-4.0.14.tar.gz
tar xvf redis-4.0.14.tar.gz -C /opt/
cd /opt/redis-4.0.14

編譯安裝

# Redis的編譯,只將命令文件編譯,將會在當前目錄生成bin目錄
make && make install  PREFIX=/usr/local/redis
cd ..
mv redis-4.0.14/* /usr/local/redis/

# 創建環境變量
echo 'PATH=$PATH:/usr/local/redis/src/' >> /etc/profile
source /etc/profile

# 此時在任何目錄位置都可以是用redis-server等相關命令
[root@redis1 ~]# redis-
redis-benchmark  redis-check-rdb  redis-sentinel   redis-trib.rb    
redis-check-aof  redis-cli        redis-server 

配置Redis

# 設置後台啟動
# 由於Redis默認是前台啟動,不建議使用.可以修改為後台
daemonize yes


# 禁止protected-mode yes/no(保護模式,是否只允許本地訪問)
protected-mode


# 設置遠程訪問
# Redis默認只允許本機訪問,把bind修改為bind 0.0.0.0 此設置會變成允許所有遠程訪問,如果指定限制訪問,可設置對應IP。
# bind指定是redis所在服務器網卡的IP,不指定本機網卡IP,可能導致你的Redis實例無法啟動
# 如果想限制IP訪問,內網的話通過網絡接口(網卡限定),讓客戶端訪問固定網卡鏈接redis
# 如果是公網,通過iptables指定某個IP允許訪問
bind 0.0.0.0

# 配置Redis日誌記錄
# 找到logfile,默認為logfile "",改為自定義日誌格式
logfile  /var/log/redis_6379.log

# 把requirepass修改為123456,修改之後重啟下服務
requirepass "123456"
# 不重啟Redis設置密碼
# 在配置文件中配置requirepass的密碼(當Redis重啟時密碼依然生效)
127.0.0.1:6379> config set requirepass test123
# 查詢密碼
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "test123"

# 密碼驗證
127.0.0.1:6379> auth test123
OK
127.0.0.1:6379> set name flying
OK
127.0.0.1:6379> get name
"flying"

# 遠程主機連接
# redis-cli  -h  redis_ip -p redis_port -a password

啟動測試

# 放到後台輸出,redis自帶日誌了,可以輸出到黑洞
nohup redis-server /usr/local/redis/redis.conf &> /usr/local/redis/redis.log &

# 關閉命令
redis-cli -h 127.0.0.1 -p 6379 -a 123456 shutdown
# 注意:不建議使用 kill -9,這種方式不但不會做持久化操作,還會造成緩衝區等資源不能優雅關閉。極端情況下造成 AOF 和 複製丟失數據 的情況。
# shutdown 還有一個參數,代表是否在關閉 redis 前,生成 持久化文件,命令為 redis-cli shutdown nosave|save。


# 設置開機自啟動
echo "redis-server /usr/local/redis.conf" >> /etc/rc.local

配置tomcat session redis同步

通過TomcatClusterRedisSessionManager,這種方式支持redis3.0的集群方式
下載TomcatRedisSessionManager-2.0.zip包,https://github.com/ran-jit/tomcat-cluster-redis-session-manager,放到$TOMCAT_HOMA/lib下,並解壓

cd /usr/local/tomcat/lib/
wget https://github.com/ran-jit/tomcat-cluster-redis-session-manager/releases/download/2.0.4/tomcat-cluster-redis-session-manager.zip
unzip tomcat-cluster-redis-session-manager.zip 
cp tomcat-cluster-redis-session-manager/lib/* ./
cp tomcat-cluster-redis-session-manager/conf/redis-data-cache.properties ../conf/
cat ../conf/redis-data-cache.properties     
#-- Redis data-cache configuration
//遠端redis數據庫的地址和端口
#- redis hosts ex: 127.0.0.1:6379, 127.0.0.2:6379, 127.0.0.2:6380, ....
redis.hosts=192.168.6.244:6379
//遠端redis數據庫的連接密碼
#- redis password (for stand-alone mode)
redis.password=pwd@123
//是否支持集群,默認的是關閉
#- set true to enable redis cluster mode
redis.cluster.enabled=false
//連接redis的那個庫
#- redis database (default 0)
#redis.database=0
//連接超時時間
#- redis connection timeout (default 2000)
#redis.timeout=2000
//在這個<Context>標籤裏面配置

vim ../conf/context.xml
<Valve className="tomcat.request.session.redis.SessionHandlerValve" />
<Manager className="tomcat.request.session.redis.SessionManager" />

配置會話到期時間在../conf/web.xml

<session-config>
<session-timeout>60</session-timeout>
</session-config>

啟動tomcat服務

[root@linux-node2 lib]# ../bin/startup.sh

Tomcat-2節點與tomcat-1節點配置相同

測試,我們每次強刷他的sessionID都是一致的,所以我們認為他的session會話保持已經完成,你們也可以選擇換個客戶端的IP地址來測試

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

※教你寫出一流的銷售文案?

※超省錢租車方案

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※回頭車貨運收費標準

信道估計(channel estimation)圖解——從SISO到MIMO原理介紹

1. 引言

在所有通信中,信號都會通過一個介質(稱為信道),並且信號會失真,或者在信號通過信道時會向信號中添加各種噪聲。正確解碼接收到的信號而沒有太多錯誤的方法是從接收到的信號中消除信道施加的失真和噪聲。為此,第一步是弄清信號經過的信道的特性。表徵信道的技術/過程稱為信道估計(channel estimation)。此過程將說明如下。

信道估計有很多不同的方法,但是基本概念是相似的。該過程如下進行。

i)設置一個數學模型,以使用“信道”矩陣將“發射信號”和“接收信號”相關。

ii)發射已知信號(我們通常將其稱為“參考信號”或“導頻信號”)並檢測接收到的信號。

iii)通過比較發送信號和接收信號,我們可以找出信道矩陣的每個元素。

作為此過程的示例,這裏簡要介紹LTE中的此過程。當然,很多細節取決於實現(這意味着具體算法可能會因每個特定的芯片組實現而有所不同)。但是,總體概念將是相似的。

2. 通用算法

我們如何找出信道的屬性?即,我們如何估計信道?從高的角度來看,可以如下圖所示。此圖显示以下內容:

i)我們嵌入了一組預定義信號(這稱為參考信號)

ii)當這些參考信號通過信道時,它會與其他信號一起失真(衰減,相移,噪聲)

iii)我們在接收方檢測/解碼接收到的參考信號

iv)比較發送的參考信號和接收的參考信號,並找到它們之間的相關性。

3. SISO的信道估計

現在讓我們考慮LTE SISO的情況,看看如何估計信道屬性(信道係數和噪聲估計)。由於考慮的是SISO系統,因此參考信號僅嵌入到一個天線端口(端口0)中。資源圖中的垂直線表示頻域。因此,這裏用f1,f2,f3 … fn索引了每個參考信號。每個參考符號可以是一個複數(I / Q數據),可以如下所示進行繪製。左側(發送側)的每個複數(參考符號)被修改(失真)為右側的每個對應符號(接收的符號)。信道估計是在左側的複數數組與右側的複數數組之間找到相關性的過程。

估計的詳細方法可能非常取決於實現方式。這裏將描述的方法基於開源:srsLTE(請參閱[1])

3.1 信道係數的估計

由於這裏只有一根天線,因此每個發射參考信號和接收參考信號的系統模型可以表示如下。y()表示接收到的參考信號的數組,x()表示發送的參考信號()的數組,h()表示信道係數的數組。f1,f2,…只是整數索引。

我們知道x()是什麼,因為給定了它,而y()也知道,因為它是從接收者處測量/檢測到的。有了這些,我們可以很容易地計算出係數陣列,如下所示。

現在我們有了參考信號所在位置的所有信道係數。但是我們需要在所有位置(包括那些沒有參考信號的點)處的信道效率。這意味着我們需要在沒有參考信號的情況下找出那些位置的信道係數。為此,最常見的方法是對測得的係數數組進行插值。在srsLTE的情況下,它首先進行平均,然後對平均信道係數進行插值。

3.2 噪聲的估計

下一步是估計噪聲特性。從理論上講,噪聲可以如下計算。

但是,我們需要的是噪聲的統計屬性,而不是確切的噪聲值。我們可以僅使用測得的信道係數和平均信道來估算噪聲,如下所示(實際上,準確的噪聲值沒有太大意義,因為噪聲值會不斷變化,使用那些特定的噪聲值沒有用)。在srsLTE中,作者使用了這種方法。

4. 2 x 2 MIMO的信道估計

假設我們有一個如下所示的通信系統。x(t)表示發送信號,y(t)表示接收信號。當x(t)傳輸到空中(信道)時,它會變形並獲得各種噪聲,並且可能會相互干擾。因此接收到的信號y(t)不能與發射信號x(t)相同。

發射信號,接收信號和信道矩陣之間的關係可以用數學形式建模,如下所示。

在此等式中,我們知道值x1,x2(已知的發射信號)和y1,y2(檢測/接收的信號)。我們不知道的部分是H矩陣和噪聲(n1,n2)。

為簡單起見,我們假設該信道中沒有噪聲,這意味着我們可以將n1,n2設置為0。(當然,在實際信道中總會存在噪聲,估計噪聲是信道估計中非常重要的一部分,但是我們在此示例中假設沒有噪音,只是為了使其簡單。稍後,當我有更好的知識以通俗的語言描述案件時,我將在案件中添加噪音)。

由於我們具有數學模型,因此下一步是傳輸已知信號(參考信號)並從參考信號中找出信道參數。

假設我們僅通過一個天線發送了幅度為1的已知信號,而另一個天線現在處於關閉狀態。由於信號通過空氣傳播,並且接收方的兩個天線都會檢測到該信號。現在,假設第一個天線接收幅度為0.8的參考信號,第二個天線接收幅度為0.2的參考信號。有了這個結果,我們可以得出如下所示的一行信道矩陣(H)。

假設我們僅通過另一個(第二個)天線發送了幅度為1的已知信號,並且第一個天線現在處於關閉狀態。由於信號通過空氣傳播,並且接收方的兩個天線都會檢測到該信號。現在,假設第一個天線接收到幅度為0.3的參考信號,第二個天線接收到幅度為0.7的參考信號。有了這個結果,我們可以得出如下所示的一行信道矩陣(H)。

夠簡單嗎?我認為理解這個基本概念沒有任何問題。但是,如果完全按照上述方法使用此方法,則可能會導致效率低下。根據上面解釋的概念,應該有一個時刻,僅發送參考信號而沒有實際數據,只是為了估計信道信息,這意味着由於信道估計過程,數據速率將降低。為了消除這種效率低下的問題,實際的通信系統會同時發送參考信號和數據。

現在的問題是“如何在同時傳輸參考信號和數據的同時實現上述概念?”。可以有幾種不同的方法來執行此操作,並且不同的通信系統將使用一些不同的方法。

以LTE為例,我們使用如下所示的方法。在LTE中為2 x 2 MIMO的情況下,每個子幀具有用於每個天線的參考信號的不同位置。天線0的子幀發送了分配給天線0的參考信號,不發送分配給天線1的參考信號的信號。天線1的子幀發送了分配給天線1的參考信號的信號,不發送給參考天線的任何信號。為天線0分配的信號。因此,如果在兩個接收器天線上解碼為天線0的參考信號分配的資源元素,則可以估計h11,h12。(在這裏,為了簡單起見,我們還假設沒有噪音)。如果在兩個接收器天線上解碼分配給天線1參考信號的資源元素,則可以估計h21,h22。

4.1 信道係數的估計

上面說明的過程是針對LTE OFDMA符號中的頻域中的一個特定點測量 \(H\) 矩陣。如果您在對符號的其他部分進行解碼的過程中照原樣應用測量的H值,則解碼的符號的準確性可能不盡人意,因為上一步中使用的測量數據會包含一定程度的噪聲。因此,在實際應用中,對通過上述方法測得的 \(H\) 值進行某種后處理,在此後處理過程中,我們可以找出噪聲的總體統計屬性(例如,噪聲的均值,方差和統計分佈))。要記住的一件事是,在此過程中獲得的特定噪聲值本身並沒有太多意義。從參考信號獲得的特定值將與用於解碼其他數據的噪聲值(非參考信號)不同,因為噪聲值是隨機變化的。然而,那些隨機噪聲的總體特性可以是重要的信息(例如,在SNR估計等中使用)。

在繼續之前,讓我們再次簡單地考慮一下數學模型。即使我們將系統方程式描述如下,其中包括噪聲項,但這並不意味着您可以直接測量噪聲。是不可能的。該方程式僅表明檢測到的信號(y)包含噪聲分量的某些部分。

因此,當我們測量信道係數時,我們使用了沒有噪聲項的設備,如下所示。

在LTE的特定應用中,我們在OFDM符號中有多個測量點(多個參考信號)。這些測量點在頻域上表示。因此,讓我們如下重寫信道矩陣以指示每個信道矩陣的測量點。

現在,假設您已經測量了整個OFDM符號上的H矩陣,那麼您將擁有多個 \(H\) 矩陣,如下所示,每個矩陣都以一個特定的頻率指示H矩陣。

現在你有了一個 \(H\) 矩陣數組。該陣列由四個不同的組組成,每個組用不同的顏色突出显示,如下所示。

當應用后處理算法時,該算法需要分別應用於這些組中的每一個。因此,為簡單起見,我將 \(H\) 矩陣的數組重新排列為多個獨立數組(在本例中為4個數組),如下所示。

對於這些數組中的每一個,我將進行如下所示的相同處理。(每個芯片組製造商都可以應用稍微不同的方法,但是總體思路是相似的)。在下面說明的方法中,數據(每個頻點中的信道係數陣列)使用IFFT進行處理,這意味着將dta轉換為時域,從而生成標記為(2)的時域數據陣列。實際上,這是特定信道路徑的脈衝響應。然後,我們對該時域數據應用特定的過濾(或加窗)。在此示例中,將某個點的數據替換為零,並創建標記為(3)的結果。您可以應用更複雜的過濾器或窗口,而不是這種簡單的調零。然後,通過將濾波后的信道脈衝數據轉換回頻域,

通過對所有四個陣列執行相同的過程,您可以獲得“估計信道係數陣列”的四個陣列。從這四個陣列中,您可以按以下方式重建估計信道矩陣的陣列。

4.2 噪聲的估計

使用此估算的信道矩陣,您可以使用以下公式估算每個點的噪聲值。這與本頁開頭的原始系統方程式相同,除了將H矩陣替換為“估計的H”矩陣外,現在我們知道除噪聲值以外的所有值。因此,通過插入所有已知值,我們可以在每個測量點計算(估計)噪聲值。

如果將此方程式應用於所有測量點,則將獲得所有測量點的噪聲值,並從這些計算出的噪聲值中獲得噪聲的統計屬性。如上所述,此處計算出的每個單獨的噪聲值沒有太大意義,因為該值不能直接應用於解碼其他信號(非參考信號),但是這些噪聲的統計特性對於確定噪聲而言可能是非常有用的信息。渠道的性質。

注意:如果您對在實際應用中如何使用此算法感興趣,強烈建議閱讀/嘗試使用Ref [2]和[3]。

參考:

[1] srsLTE:\ srslte \ lib \ ch_estimation \ chest_dl.c-srslte_chest_dl_estimate_port()

[2] 信道估計(Mathworks,LTE工具箱)

[3] NR同步程序

[4] http://www.sharetechnote.com/html/Communication_ChannelEstimation.html#General_Algorithm

更多精彩內容請關注訂閱號優化與算法和加入QQ討論群1032493483獲取更多資料

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※別再煩惱如何寫文案,掌握八大原則!

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※超省錢租車方案

※教你寫出一流的銷售文案?

網頁設計最專業,超強功能平台可客製化

※產品缺大量曝光嗎?你需要的是一流包裝設計!

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

「從零單排canal 01」 canal 10分鐘入門(基於1.1.4版本)

1.簡介

canal [kə’næl],譯意為水道/管道/溝渠,主要用途是基於 MySQL 數據庫增量日誌解析,提供增量數據 訂閱 和 消費。應該是阿里雲DTS(Data Transfer Service)的開源版本。

2.提供的能力

Canal與DTS提供的功能基本相似:

1)基於Mysql的Slave協議實時dump binlog流,解析為事件發送給訂閱方。

2)單Canal instance,單DTS數據訂閱通道均只支持訂閱一個RDS,提供給一個消費者。

3)可以使用canal-client客戶端進行消息消費。

4)也可以通過簡單配置,也可以不需要自行使用canal-client消費,可以選擇直接投遞到kafka或者RocketMQ集群,用戶只需要使用消息隊列的consumer消費即可。

5)成功消費消息后需要進行Ack,以確保一致性,服務端則會維護客戶端目前的消費位點。

3.工作原理

MySQL的主從複製分成三步:

  • master將改變記錄到二進制日誌(binary log)中(這些記錄叫做二進制日誌事件,binary log events,可以通過show binlog events進行查看);
  • slave將master的binary log events拷貝到它的中繼日誌(relay log);
  • slave重做中繼日誌中的事件,將改變反映它自己的數據。

 

canal 就是模擬了這個過程。

  • canal模擬 MySQL slave 的交互協議,偽裝自己為 MySQL slave ,向 MySQL master 發送 dump 協議;
  • MySQL master 收到 dump 請求,開始推送 binary log 給 slave (即 canal );
  • canal 解析 binary log 對象(原始為 byte 流);

 

4. canal 架構

4.1 admin版本整體架構

canal 1.1.4開始支持admin管理,通過canal-admin為canal提供整體配置管理、節點運維等面向運維的功能,提供相對友好的WebUI操作界面,方便更多用戶快速和安全的操作,替代了過去繁瑣的配置文件管理。

整體部署架構如下。

 

  • 多個canal-server可以組成集群模式,每個instance任務通過zookeeper在集群中實現高可用
  • 通過多個集群,可以實現同步資源的物理隔離
  • 可以直接抓取消費投遞MQ,可以實現生產/消費解耦、消息堆積、消息回溯
  • 可以抓取消費投遞給canal-client,在用戶的服務中進行消息處理,減少中間過程

4.2 canal-server架構

 

說明:

  • server代表一個canal-server運行實例,對應於一個jvm
  • instance對應於一個數據隊列,是真正的變更抓取的實體 (1個server可以對應多個instance)

Instance模塊

  • EventParser :數據源接入,模擬slave協議和master進行交互,協議解析
  • EventSink :Parser和Store鏈接器,進行數據過濾,加工,分發的工作
  • EventStore :數據存儲
  • MetaManager:增量訂閱&消費信息管理器

1)EventParser子模塊

EventParser模塊的類圖設計如下

 

每個EventParser都會關聯兩個內部組件:CanalLogPositionManager , CanalHAController

  • CanalLogPositionManager:記錄binlog最後一次解析成功位置信息,主要是描述下一次canal啟動的位點
  • CanalHAController:支持Mysql主備,判斷當前該連哪個mysql(基於Heartbeat實現,主庫失去心跳則連備庫)

EventParser根據HAController獲知連到哪裡,通過LogPositionManager獲知從哪個位點開始解析,之後便通過Mysql Slave協議拉取binlog進行解析,推入EventSink

2)EventSink子模塊

目前只提供了一個帶有實際作用的實現:GroupEventSink

GroupEventSink用於將多個instance上的數據進行歸併,常用於分庫后的多數據源歸併。

3)EventStore子模塊

EventStore的類圖如下

 

官方提供的實現類是
MemoryEventStoreWIthBuffer,內部採用的是一個RingBuffer:

 

  • Put : Sink模塊進行數據存儲的最後一次寫入位置
  • Get : 數據訂閱獲取的最後一次提取位置
  • Ack : 數據消費成功的最後一次消費位置

這些位點信息通過MetaManager進行管理。這也解釋了為什麼一個canal instance只能支撐一個消費者:EventStore的RingBuffer只為一個消費者維護信息。

4.3 客戶端使用

數據格式已經在前文給出,Canal和DTS客戶端均採取:

拉取事件 -> 消費 -> 消費成功后ACK

這樣的消費模式,並支持消費不成功時進行rollback,重新消費該數據。

下面是一段簡單的客戶端調用實例(略去異常處理):

// 創建CanalConnector, 連接到localhost:11111

CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress(AddressUtils.getHostIp(),11111), destination, "", "");

connector.connect(); // 連接

connector.subscribe(); // 開始訂閱binlog

// 開始循環拉取

while (running) {

Message message = connector.getWithoutAck(1024); // 獲取指定數量的數據

long batchId = message.getId();

for (Entry entry : message.getEntries()){

// 對每條消息進行處理

}

connector.ack(batchId); // ack

}

5.總結分析

5.1 優點

1)性能優異、功能全面

  • canal 1.1.x 版本(release_note),性能與功能層面有較大的突破,重要提升包括:
  • 整體性能測試&優化,提升了150%. #726
  • 原生支持prometheus監控 #765
  • 原生支持kafka消息投遞 #695
  • 原生支持aliyun rds的binlog訂閱 (解決自動主備切換/oss binlog離線解析) (無法拒絕它的理由!)
  • 原生支持docker鏡像 #801

2)運維方便

  • canal 1.1.4版本,迎來最重要的WebUI能力,引入canal-admin工程,支持面向WebUI的canal動態管理能力,支持配置、任務、日誌等在線白屏運維能力
  • Standalone的一體化解決方案,無外部服務依賴,運維更簡單,在某種程度上也意味着更穩定。
  • 開箱即用,節約開發與定製成本。
  • 有良好的管理控制平台與監控系統(如果你已經有promethus監控,可以秒接canal監控)

3)多語言支持

  • canal 特別設計了 client-server 模式,交互協議使用 protobuf 3.0 , client 端可採用不同語言實現不同的消費邏輯
  • canal 作為 MySQL binlog 增量獲取和解析工具,可將變更記錄投遞到 MQ 系統中,比如 Kafka/RocketMQ,可以藉助於 MQ 的多語言能力

5.2 缺點

  • 單instance/訂閱通道只支持訂閱單個數據庫,並只能支持單客戶端消費。每當我們需要新增一個消費端->MySQL的訂閱:對於Canal而言,就要給MySQL接一個“Slave”,可能會對主庫有一定影響。
  • 消息的Schema很弱,所有消息的Schema均相同,客戶端需要提前知道各個表消息的Schema與各字段的上下文才能正確消費。

好了,花了10分鐘應該對canal有大致了解了,下一期,阿丸計劃手把手教你搭建canal集群和admin管理平台,記得關注哦。

 

都看到最後了,原創不易,點個關注,點個贊吧~

知識碎片重新梳理,構建Java知識圖譜: github.com/saigu/JavaK…(歷史文章查閱非常方便)

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※教你寫出一流的銷售文案?

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

※超省錢租車方案

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※推薦台中搬家公司優質服務,可到府估價

小米11 Pro 新外觀渲染圖、規格曝光?!小米11 系列還有兩款高階機型尚未推出,不過小米10 將有 S870 小改升級版本

除了幾天後將舉行的小米11 全球發表會,屆時預計最快在三月間台灣消費者也有機會購入小米11 旗艦新機。而小米11 系列其實還有包括「大杯」的小米11 Pro 和「超大杯」的小米11 Pro+(或稱為小米11 Ultra)還沒有正式亮相。不過在小米的「友商」Redmi 已經確定將在本月發表全新 Redmi K40 系列新機後,預期這兩款未推出的小米11 系列高階機型得等到三月才會正式揭曉。

▲圖片來源:@xiaomiui(Telegram)

小米11 Pro 新外觀渲染圖、規格曝光?!小米11 系列還有兩款高階機型尚未推出,不過小米10 將有 S870 小改升級版本

從 @xiaomiui 這 Telegram 爆料的小米11 Pro 渲染圖,在主相機設計和小米11 並沒有太大不同,最顯著的差異在閃光燈改設計在主鏡頭的環形 LED 補光燈設計。
規格方面,小米11 Pro、小米11 Pro+預計搭載 6.81 吋 2K 解析度、120Hz 螢幕更新率、採用三星 E4 發光材料的 SuperAMOLED 曲面螢幕,在螢幕規格方面大致和小米11 標準版保持一致。硬體規格方面,則同樣搭載高通 Snapdragon 888 處理器、 LPDDR5 RAM 和 UFS3.1 ROM。
相機部份則是這三款小米11 之間最顯著的差異,其中小米11 Pro 預計搭載 5000 萬像素(Samsung ISOCELL GN2 感光元件)主鏡頭、4800 萬像素超廣角鏡頭和 4800 萬像素 5x 潛望式長焦鏡頭(支持 120x 混合變焦拍照、 15x 變焦錄影)。
其他方面,傳聞電池內建等效 5000mAh 容量大電池,其中最高規的小米11 Pro+(小米11 Ultra)預計支持最高 120W 有線快充、67W 無線快充。

▲圖片來源:@xiaomiui(Telegram)

不過回顧數碼閒聊站之前在微博提到小米11 Pro 的主相機矩陣模組比起之前更大、辨識度更高,因此這次 @xiaomiui 釋出的渲染圖其實可信度並不高。
據傳小米近期也將推出多款新機,除了幾天後小米11 將在全球發表,接下來小米10 系列將帶來更新處理器的新版本、小米11 系列則有小米11 Pro 和小米11 Ultra(或稱小米11 Pro+) ,至於 Redmi K40 系列以及 Redmi 遊戲手機預計在本月下旬也會亮相。

▲圖片來源:數碼閒聊站(微博)

相比之下,其實上個月 Ben Geskin 根據傳聞製作的小米11 Pro 概念渲染圖外觀或許還比較接近未來小米11 Pro 真正的樣貌:

▲圖片來源:Ben Geskin(Twitter/ @BenGeskin)

至於數碼閒聊站之前微博提到小米10 有款神秘新機,日前也表示小米10 新版本通過認證,和之前搭載高通 Snapdragon 865 處理器的小米10 之間最大的差異在於升級為高通 Snapdragon 870 ,其餘規格則相同。另外,從近期小米官方、雷軍等人微博的貼文動態已多次提及小米10 來看,確實在不久後可能帶來這款小幅升級的全新小米10 。

▲圖片來源:數碼閒聊站(微博)

消息來源:@xiaomiui(Telegram)

延伸閱讀:
華碩傳聞將在今年推出小尺寸旗艦 ZenFone mini , ROG Phone 5 於 4 月推出、價格將高於 ROG Phone 3

小米首款「四曲瀑布螢幕概念手機」正式亮相!四邊 88° 超曲面螢幕、螢幕下前鏡頭、整機一體無孔化設計

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

【其他文章推薦】

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※回頭車貨運收費標準

※推薦評價好的iphone維修中心

※超省錢租車方案

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

※推薦台中搬家公司優質服務,可到府估價

為什麼其他無線藍牙耳塞無法像 Apple AirPods 一樣賣到翻掉?

雖然市面上充斥大量的真無線藍牙耳塞產品,但毫無疑問地,沒有人能夠撼動 Apple AirPods 的地位。在 2020 年 AirPods 佔據了將近一半的市場占比,即使像是 Samsung、小米這樣同樣極具份量的廠牌,就算在智慧型手機的領域銷售驚人,但一跨到真無線藍牙還是得俯首稱臣。到底為什麼 AirPods 這麼受歡迎呢?說是行銷也好,但事實上原因卻更複雜些。

為什麼其他無線藍牙耳塞無法像 Apple AirPods 一樣賣到翻掉?

Apple 在一定程度透過從上至下的一體性封閉控制來成長,使得它比競爭對手更具優勢,其他就是剛好在正確的時機,以及其他產品缺乏創意的競爭。一直以來,評論員們喜歡抨擊 Apple 創造了一個牆內的世界,你很難離開、跨越而不失去常用、實用的功能,甚至整個設備也在範圍之內。舉例來說,你可以把 AirPods  搭配 Android 手機或 Windows 電腦一起使用,但你將會失去 iPhone、 Apple Watch 和 Mac 之間緊密的整合。相比之下與平台毫無關係的真無線藍牙耳塞則提供跨平台同樣功能,甚至讓你可以選用語音助理,從理論上來說,如果你選擇從 Apple 體系跳槽就沒有什麼理由再去擁抱 Apple。

然而也就是這種封閉使得 AirPods 如此具吸引力。Apple 控制著旗下的硬體軟體,始知能夠整合發揮出競爭對手所無法使用或需要額外手續、時間才能做到的功能。例如,Apple 可以說是第一家真正讓用戶可以輕鬆配對與管理真無線藍牙耳塞的公司,藉由輕撫外殼就能在幾秒鐘內讓手機與耳機之間相互連接使用而無需久候。Apple 就是利用這種嚴謹的控制在競爭對手間保持領先地位,Apple 可能並沒有擁有最佳音質、電池續航時間或相容性,但它具有持續設定和提高期望值的更大的優勢,AirPod 通常使用不費力,並且可以依靠軟體作動,Apple 使得其他公司很難在需要支援更廣泛的設備和作業系統時跟上。

雖然時機不是一切,但抓住時機很重要

從歷史紀錄看來,Apple 很少第一個跨足新的設備類別,就像 iPod 絕對不是第一款 MP3 播放器,iPhone 也不是第一部智慧型手機,然而他們卻把握住了即早切入的要點,除了擾亂一波池水,還能從先驅者們的錯誤中吸取教訓,AirPods 就是抓住最佳時機的例子。藍牙耳塞這類產品早在 Apple 於 2016 年推出第一款 AirPods 之前就已經誕生,但用戶數量才剛剛起飛,而且市面上的耳塞也擁有諸多限制,像是電池續航時間短,頸後的連接線和複雜的配對過程。在 AirPods 推出後,將整個過程簡化,也解決了電池續航、外型等通點,並且做到真正的無線。

Apple 的行銷影響力在 AirPods 的成功中扮演了重要角色。相對龐大的尺寸保證了很多人會知道 AirPods 的存在,Apple 透過移除 iPhone 7 上的耳機插孔, 重推了 Airpods 一把。不過,如果 AirPods 來得太晚,或者失去有意義的優勢,這兩項後續的作法都無濟於事,行銷力量只確保 AirPods 或許有最強的開始, 卻不能保證成功。

競爭對手的創意匱乏,只有眾多的致敬品

你可以在市面上找到其他高品質的真無線藍牙耳塞,但更多的是充斥著大量明顯有著 AirPods 影子的耳塞,特別是中國廠商前仆後繼地推出或許外型上存在部分差異,卻怎麼也跳不出 Apple 設計的框架,缺乏真正亮眼、出彩的特色,使得預算較充足的消費者大多不會選擇一個「仿冒品」。

不管獨特性如何,所有的競爭對手都面臨同一個問題:「沒有從根本上改變 Apple  AirPods 的基本概念」。雖然現在市面上其他品項看起來音質更好、續航更長,但卻沒有革命性的技術提升,使得消費者不禁躊躇不前。當 AirPods 在銷售數字上遙遙領先時,這一切都還不夠,雖說這些競爭對手的確為 Android 用戶帶來與 AirPods 一樣的功能,但真正會考慮入手 AirPods 的人,除非預算有限或是真正地深入去進行實驗對照,否則可能不會對其他替代方案產生關注。

從目前整體的市場態勢上來看,要想撼動 AirPods 的地位,可能需要在真無線藍牙耳塞技術上發生重大變化,才比較有可能讓 AirPods 搖兩下,但這或許在很長一段時間裡面並不會發生。

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

【其他文章推薦】

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

※教你寫出一流的銷售文案?

※超省錢租車方案

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※回頭車貨運收費標準

疑似 realme Race S888 旗艦新機外觀曝光!預計 3 月正式發表

在小米11 推出一陣子後,過完農曆新年也將有許多搭載高通 Snapdragon 888 處理器的旗艦新機將發表,其中許多人相當關注 realme 早早就預告「首批」搭載高通 Snapdragon 888 的代號 Race 的神秘新旗艦,至今官方除了聲明 Race 為內部代號而非產品型號外,並未對外有產品的進一步爆料。不過,在今日稍早網路流傳著疑似 realme Race(暫稱)的外觀照片現身中國工信部的照片,據悉這款新機將在 3 月登場。

疑似 realme Race S888 旗艦新機外觀曝光!預計 3 月正式發表

在 OPPO Find X3 系列中的 Find X3 Pro 規格重點、外觀都已經被爆料差不多的同時, realme 至今仍對於品牌首款搭載 Snapdraogn 888 旗艦 5G 處理器的新機仍是保密到家。

▲圖片來源:徐起Chase(微博)

除了 realme 副總裁徐起在微博透露春節後這款新機將會登場,其餘關於 realme 這款新旗艦的名稱、外觀、規格都是只停留在傳聞階段。

▲圖片來源:徐起Chase(微博)

▲圖片來源:徐起Chase(微博)

不過稍早數碼閒聊站微博一度發文刊出疑似 realme Race 在中國工信部認證的外觀圖片,不過很快也再次編輯該篇貼文但至今未刪文:

▲圖片來源:數碼閒聊站(微博)

這幾張工信部的照片透露的手機圖片外觀可以看到,這款手機採用左上角採單挖孔的平面全螢幕設計,機身背面的主相機設計和目前多款 realme 雷同,不過在機身背面有著 GT 字樣。至於相機規格目前還無法得知,不過據過去傳聞將配備四鏡頭主相機設計:

▲圖片來源:TENAA

從機身側邊看來也相當輕薄:

▲圖片來源:TENAA

至於這款手機型號為 RMX2202 ,回顧過去洩漏的資訊,傳聞這款新機除了搭載高通 Snapdragon 888 處理器,將配備 12GB RAM 和 256GB ROM ,傳聞將支持最高 125W UltraDART 快速充電。在軟體方面,運行 realme UI 2.0 介面和 Android 11 作業系統。

▲圖片來源:TENAA

延伸閱讀:
realme V11 海外發表:搭載聯發科天璣 700 的輕薄大電量入門 5G 手機

小米MIX系列「可量產」新機確認將在今年即將回歸,另有小米平板也將登場

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

【其他文章推薦】

※別再煩惱如何寫文案,掌握八大原則!

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※超省錢租車方案

※教你寫出一流的銷售文案?

網頁設計最專業,超強功能平台可客製化

※產品缺大量曝光嗎?你需要的是一流包裝設計!

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

Chrome 變萌了,教你如何製作小恐龍 QR Code 分享網址

雖然前段時間的爭議,但無損 Chrome 在瀏覽器界執牛耳的地位,在上周推出的最新版 Chrome 88 更新中藏了一個有點兒萌的小彩蛋,讓你在與朋友透過 QR Code 分享網頁時可以看到招牌小恐龍,雖然不是什麼驚天地的大功能,但還是非常可愛,不只手機,電腦版的 Chrome 瀏覽器也有喔!

Chrome 變萌了,教你如何製作小恐龍 QR Code 分享網址

在 Google 於 2/4 推出的 Chrome 88 更新中,你可以用 QR Code 直接與朋友分享,在瀏覽器上即時顯示 QR Code,輕輕一掃就可以直接前往,就算沒有在社群軟體互加好友也可以快速分享有趣網站。這個新功能怎麼用呢?

行動裝置版

  • 開啟 Chrome 瀏覽器後,點選想要分享出去的網頁右上角菜單圖示,並從中選擇「分享」這一項。

  • 在分享方式中選擇 QR Code 圖碼,即可立刻看到小恐龍 QR Code,朋友只需掃一下就可快速造訪該網站。

電腦版

  • 首先點一下網址列,然後可以看到網址列最右邊出現 QR Code 圖示。

  • 點選後會以子視窗的方式顯示小恐龍 QR Code,你也可以選擇將這個 QR Code 下載留待之後使用。

雖然很多人會認為直接將網址 LINE 過去不是比較快?但是很多情況下身旁的人並不在你的好友名單中,而你也並不想只為了一次性的需要而加入不熟或其實並不認識的人,這個時候利用QR Code 來快速分享就方便多了!

 

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

【其他文章推薦】

※教你寫出一流的銷售文案?

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

※超省錢租車方案

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※推薦台中搬家公司優質服務,可到府估價