2020年5月20日 星期三

nodejs上RabbitMQ 使用amqplib 紀錄

在nodejs上實作rabbitMQ的client端
使用amqplib module
依照文件做一些紀錄

Overview
  1.在與RabbitMQ建立連線connection後
    在connection上是可以建立多個channel
  2.RPC端透過AMQP與Server連接 都是透過非同步的方式的溝通
    也就是說 RPC不是直接與RPC溝通 而是透過中介的RabbitMQ Server
    傳送與接收
    因此大多數amqplib提供的操作method 並不會由server取得回應
    或只是接收到boolean的回傳值
Dealing with failure
  大多數AMQP的操作,只要沒達到預期的狀態就會當作錯誤
  因為錯誤可能造成channel關閉,錯誤發生或可能產生的效應
  1.目前發生錯誤的RPC會被reject
  2.使用的channel物件會因為錯誤 造成之後的操作發生問題
  3.任何等待傳送的RPC 都會被reject
  4.造成channel物件emit 'error'
  5.造成channel物件emit 'close'
  當channel發生錯誤有可能是其他的RPC所造成
  而非當下連線的RPC造成
  要去找到問題發生原因可以透過
  try catch捕捉到錯誤e的stackAtStateChange會是有用的錯誤資訊
connection.createChannel().then(function(ch) {
  ch.close();
  try {
    ch.close();
  }
  catch (alreadyClosed) {
    console.log(alreadyClosed.stackAtStateChange);
  }
});

Flow Control
channel的運作會類似於stream.Writable
  1.當呼叫publish或sendToQueue時會回傳
    true:代表 'keep sending'
    false:代表 please wait for a 'drain' event
  2.呼叫以下這些method則不會有任何server的回傳
    包括ack, ackAll, nack, nackAll, and reject
  3.ConfirmChannel則會以callback來接收boolean值
    當server有確認了message時 callback會被呼叫

Argument handling
  許多的method操作都會吃一個option參數
  option本身有一些預設的option參數值
  如果傳入非option定義的參數內容會被忽略
  通常會把option合併成一個單一物件便於使用
var common_options = {durable: true, noAck: true};

var bar_opts = Object.create(common_options);
bar_opts.autoDelete = true;

var foo_consume_opts = Object.create(common_options);
// 使用arguments table方式priority,必須以x-格式寫, 
foo_consume_opts.arguments = {'x-priority': 10};

var bar_consume_opts = Object.create(foo_consume_opts);
// 覆寫之前已經設定的prooprity值
bar_consume_opts.priority = 5;

Field table values
  在publish與sendToQueue的option內
  包括arguments與headers都是 field table值
  都是key-value object型式
  有一些特別的value型態會在table內被encode
  當js內會以!語法來標明其型態
ex:
  {'!': 'int8', value: 64}
  {'!': 'decimal', value: {digits: 4999, places: 2}}

2020年5月15日 星期五

RabbitMQ noAck設定

當接收者設定監聽訊息時 可以設定是否要回應MQ

noAck:true 表不需做任何確認
也就是說MQ將訊息送給consumer(接收者)後
就會立刻把這筆訊息由queue清掉

預設noAck為false
當producer送出訊息到MQ上
MQ將會通知有設定監聽的consumer
接收端在設定接聽時可以透過noAck設定是否必須要回應MQ
noAck:fasle 表一定要回應讓MQ知道工作已完成
若沒有回應,則訊息還在MQ內並不會被清除
下次還是會再重送
consumer的確認動作
只要執行channel.ack(msg)就可以了
注意 這裡的msg是由mq送過來的訊息物件
不要做任何修改 直接當作ack的參數

當接收者不在線上
sender發出後
當接收者後來才上線
無論noAck設定為何都會收到

2020年4月28日 星期二

fcm 推播 icon必須是只有白色

測試FCm推播
踩到一個雷點 分享一下
android 7之後(包括7)
推播notify icon必須是只有白色
用原本的icon都會變一片空白
以下網址可以驗證並產生推播用的icon
http://romannurik.github.io/AndroidAssetStudio/icons-notification.html#source.type=image&source.space.trim=1&source.space.pad=0&name=fcm_push_icon

在 AndroidManifest.xml的applications內加入
使用fcm icon 設定
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/fcm_push_icon" />

其中fcm_push_icon是存在於res/draw-xxx/ 各目錄下icon檔案名稱

2020年4月24日 星期五

git 查詢commit 紀錄

今天遇到一個曾經遇過的問題
但已經忘記之前是怎麼解決
一個維護較長時間的專案 往往有一堆的commit
要從過去的commit紀錄內爬到自己要找的那個commit
當然不可能一個個去翻
透過指令 是最好的方法
git log --all --grep='htc'

安裝與設定使用 nginx docker

利用nginx docker取代在系統內安裝的nginx
1.基本docker指令

docker images 察看本機已下載的image
docker container list 察看本機上已經建立的container
docker ps 列出正在運行的container
docker stop containerID 停止container運作
docker container rm containerId 刪除container
docker image rm imageName 刪除image

2.初始安裝nginx
docker run --name=mynginx nginx -p 3838:80
  以nginx這個image安裝 命名為mynginx的container
  並將docker內部的80 port 對應到外部(host)使用的3838 port
  若本機並不存在nginx image會自動由網路下載安裝

3.進入nginx container 察看目錄
docker exec -it mynginx bash
  進入container 內察看設定檔的目錄準備用來對應到本機目錄使用
  查到nginx目錄在container內的
  /etc/nginx
  www根目錄在
  /usr/share/nginx/html

4.將nginx 設定檔與html目錄對應到本機上
  在本機上建立目錄用來對應
  ~/docker_share/nginx/html 對應html目錄
  ~/docker_share/nginx/conf 對應nginx設定檔
  設定nginx.conf單一檔案的對應需要使用:ro readyonly模式
  重新建立 container
docker run --name=mynginx -d -v ~/docker_share/nginx/html:/usr/share/nginx/html 
  -v ~/docker_share/nginx/conf:/etc/nginx/conf.d -v ~/docker_share/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
  -p 3388:80 nginx
  若原container已存在可停止刪除再安裝

5.重啟nginx
  重啟nginx 的指令為 nginx -s reload
  可透過exec指令執行container內部指令
docker exec -d mynginx nginx -s reload
  當然也可以透過
  docker exec -it mynginx bash 直接開shell進入container
  再執行
  nginx -s reload