0%

前言

在 Rabbitmq 官方 Github 有開源一個 k8s 操作管理 RabbitMQ clusters 環境 cluster-operator.

這個專案在2020啟動,我個人覺得官方有些說明還沒很完善,本篇文章跟大家介紹如何去使用

建立 operator

1
kubectl apply -f https://github.com/rabbitmq/cluster-operator/releases/latest/download/cluster-operator.yml

下面的yaml檔案是建立一個RabbitmqCluster

1
2
3
4
5
6
apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: hello-world
spec:
replicas: 3

透過 kubectl apply -f {your yaml filename} 後就可以透過 kubectl get all 查看 RabbitMQ cluster 是否建立完成

如果建立完成會出現類似下圖

Read more »

前文

k8s前身是Google開發borg系統,用於管理Google系統,後面由許多borg核心開發人用利用Go語言改寫就造就Kubernetes

可以根據聲明式設定,管理、擴展我們的容器化應用編排系統

  • 有效安全幫我們執行Container Rollout
  • 能夠因應系統流量變化,進行伸縮擴容(Scaling)
  • Health check實現自動偵測故障及重啟功能
  • 透過Namespace有效幫我們做資源隔離

k8s協助我們方便掌控複雜容器系統架構,具有良好伸縮性

建議在閱讀k8s文章前先要有Docker相關知識,不然許多點會有看沒有懂

我們練習會使用k3d使用Docker建議k8s來練習

k8s 主要組件介紹

先來張圖(此圖來自wiki)wiki畫的很棒,我拿來借用一下XDD

Read more »

前文:

我們在撰寫C#時常常會聽到CLR(Common Lnguage Rumtime),但對於CLR又認知多少呢?

本篇會跟大家介紹CLR基本且核心的物件

CLR 簡介

編譯器在編譯時把(C#,VB,F#….)進行編譯檢查跟把程式碼轉成MSIL中繼資料,在運行期間透過JIT(just in time)會在程式運行期間把MSIL轉成每個機器可以執行組合語言

大概可以理解為下圖

這邊我不探討Management和UnManagement物件
MSIL也算是微軟開發語言的一個抽象

SOS Debuger

注意你的電腦是 x86 or x64

Read more »

前言

你知道object lock底層怎麼實作,可重入鎖是底層是怎麼運作的嗎?

本篇就跟大家分享這些細節.

可重入鎖Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Program
{
static object _object = new object();

static void Main(string[] args)
{
Task.WaitAll(Task.Run(() => { TryLockDemo(); }), Task.Run(() => { TryLockDemo(); }));

Console.WriteLine("Hello World!");
}

public static void TryLockDemo() {
var threadId = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine($"[{threadId}] {DateTime.Now:HH:mm:ss} TryLockDemo Start");
try
{
Monitor.Enter(_object);
Console.WriteLine($"[{threadId}] {DateTime.Now:HH:mm:ss} get first lock");
try
{
Thread.Sleep(3000);
Monitor.Enter(_object);
Console.WriteLine($"[{threadId}] {DateTime.Now:HH:mm:ss} get second lock");
}
finally
{
Monitor.Exit(_object);
Console.WriteLine($"[{threadId}] {DateTime.Now:HH:mm:ss} release second lock");
}
}
finally
{
Thread.Sleep(3000);
Monitor.Exit(_object);
Console.WriteLine($"[{threadId}] {DateTime.Now:HH:mm:ss} release first lock");
}
}
}

上面這段程式碼,同時間會由2個Thread來呼叫處理TryLockDemo方法.

主要是演示lock中在對於同一個object lock一次且在multiple-Thread中會怎麼運作

為什麼Thread 1釋放first lock時,Thread 2會繼續blocking並等待Thread 1釋放second lock?

object中Syncblk

Read more »

前言

假如你寫過多執行緒系統一定會看過volatile,但你對他的了解有多少?

MSDN對於volatile關鍵字解釋如下.

volatile 關鍵字指出某個欄位可能是由同時執行的多個執行緒所修改。 編譯器、執行階段系統,甚至硬體都有可能基於效能因素,而重新排列對記憶體位置的讀取和寫入。 宣告為 volatile 的欄位不受限於這些最佳化考量。 加入 volatile 修飾詞可確保所有的執行緒都會依執行寫入的順序,觀察任何其他執行緒所執行的暫時性寫入。

MSDN上寫一堆文謅謅的解釋,如果沒有相對應OS或底層概念會很難理解上面敘述

volatile 三大特性

這裡我先總結volatile三大特性

  1. volatile修飾的變數具有可見性
  2. volatile避免指令優化重排
  3. volatile不保證Atomic

本文會針對這三大特性來一一解釋

注意在執行本文程式碼時要把Build Mode改成Release.

Read more »

前言

在多執行緒系統中,Thread的執行和長短是交由OS來幫我處理了

假如有一個面試題目是

  • 目前有三個Thread 每個Thread個別負責Print “A”,”B”,”C”

  • 要求:利用三個Thread並按照A,B,C順序打印出20次資訊,中間不能錯號

    ex:
    A
    B
    C
    A
    B
    C

程式碼框架如下,在Main函式建立3個Threads分別負責A,B,C字母打印

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class Program
{
static void Main(string[] args)
{
Alternate c = new Alternate();
var t1 = new Thread(c.CallA);
var t2 = new Thread(c.CallB);
var t3 = new Thread(c.CallC);

t1.Start();
t2.Start();
t3.Start();

t1.Join();
t2.Join();
t3.Join();

Console.ReadKey();
}
}
public class Alternate
{
public void CallA()
{
for (int i = 0; i < 20; i++)
{
Console.WriteLine("A");
}

}

public void CallB()
{
for (int i = 0; i < 20; i++)
{
Console.WriteLine("B");
}

}
public void CallC()
{
for (int i = 0; i < 20; i++)
{
Console.WriteLine("C");
}
}
}

因為Thread被呼叫順序是由OS跟CPU來決定,目前執行如下圖所以目前打印出來的順序是無序的

期望可以打印出如下圖

Read more »

前言

在之前我有寫一篇關於資料庫的ACID分享RDBMS資料庫基本原則

假如我們系統是一個多執行續高併發系統也要注意Atomic不然會造成資料會有Data Racing導致bug產生..

本文使用範例在我github上CAS_Lock有興趣的人可以參考.

沒有注意Atomic會導致的問題

我是我們公司擔任技術面試官之一,假如面試者說他實作過高併發系統

我就會先問以下問題來辨別是否要更深入面試高併發系統相關問題.

下面Sample Code是這樣.

我用Task假裝高併發,下面有一個Member類別預設給100000元的Balance

有一個UpdateBalance每呼叫一次就扣10元,我透過For跑10000次

Read more »

前言

假如我跟你說下面語法在高併發系統,UserId = 101餘額會扣到變負值你們知道問題出在哪裡嗎?

本篇會跟大家解析問題所在(DB Isolation重要性)

建立樣本資料 & 問題解釋

我建立一個資料表UserAccount並建立一個PK在UserID欄位上,裡面Patch一筆資料Userid = 101餘額有100元

1
2
3
4
5
6
7
8
9
CREATE TABLE dbo.UserAccount(
UserID INT NOT NULL,
Balance DECIMAL NOT NULL
PRIMARY KEY (
UserID
)
);

INSERT INTO dbo.UserAccount VALUES (101,100);

執行扣款有bug版腳本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
BEGIN TRAN
DECLARE @UserID INT = 101,
@Balance DECIMAL(18,4) = 1

IF EXISTS(
SELECT 1
FROM dbo.UserAccount
WHERE UserID = @UserID
AND Balance >= @Balance
)
BEGIN
UPDATE dbo.UserAccount
SET Balance = Balance - @Balance
WHERE UserID = @UserID
END

COMMIT TRAN

明明上面有使用Transatcion但為什麼還是會扣成負值?

壓力測試數值介紹 & 問題重現

Read more »

前文

現今越來越多系統使用MQ來達成非同步並來提升系統吞吐量,我今天想要介紹的是EasyNetQ一個封裝RabbitMq Client .net框架

  • 小型DI容器
  • 對於RabbitMq封裝
  • 對於連接使用lazy connection連接RabbitMq

If the server disconnects for any reason (maybe a network fault, maybe the RabbitMQ server itself has been bounced), EasyNetQ will revert to polling the endpoint until it can reconnect.

使用EasyNetQ來操作RabbitMq簡單很多,但在使用上有些地方需要注意

本篇會再跟大家分享

RabbitMq Client vs EasyNetQ程式碼比較

我會使用之前使用RabbitMq Client寫的範例利用EasyNetQ來改寫一次.

程式原始碼 Sample Code

Publisher程式碼

Read more »

前文

最近面試有一間公司要求使用Restcountries API使用CRUD前端Html串接API,有看我文章的夥伴應該知道我大多是研究後端或CI/CD相關技術,對於前端技術較少研究,這次我打算使用vue.js來完成此次需求.

需求如下

  1. 分頁
  2. 顯示國家相關資訊
  3. 排序效果
  4. 點選國家名稱進入Detail頁面

因為以上幾點都是CRUD相關操作,關於CRUD相關操作使用三大框架就很適合(所以我選擇使用Vue)

話不多說先給大家看看成品 RestcountriesSample

Source Code

要使用的API介紹

雖然官網對於API介紹雖少,但我相信只要有常串API的人應該可以很快猜出每個API作用.

  • All:請求所有國家資訊
  • FULL NAME:查找國家By名子.
Read more »