集群部署專題之二:超高性能RPC框架Zeroc-ICE集群部署簡易教程

来源:https://www.cnblogs.com/xl-xueling/archive/2023/09/01/17670837.html
-Advertisement-
Play Games

### 歡迎訪問我的GitHub > 這裡分類和彙總了欣宸的全部原創(含配套源碼):[https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) ### 題目描述 - 難度:中等 - 給定一個不含重覆數字的數 ...


一、前言

Zeroc ICE在簡中互聯網的資料十分匱乏,以至於大家線上使用時可能會有所顧慮。其實大家盡可放心,ZerocICE是一款性能和穩定性都非常優秀的RPC組件,這也是我當時選擇ZerocICE作為XL-LightHouse的RPC組件的唯一原因。為便於大家快速瞭解ZerocICE,本文以v3.7版本為例介紹其部署和使用方式。

二、特性

  • 跨語言通信
  • 高性能RPC
  • 安全通信
  • 實時壓縮
  • 註冊中心支持主從備份
  • 節點負載均衡,可動態調整
  • 支持同步調用和非同步調用

三、名詞解釋

1、Slice語義
ZerocICE目前支持的開發語言有:C++、Java、C#、JavaScript、Python、Ruby、Swift、Objective-C、PHP。通過Slice語義,不同語言開發的客戶端和服務端可以完全互通。Slice語義可以理解成一種描述介面構成(介面名稱、介面參數類型、返回值類型)的標準。ZerocICE提供了Slice轉化工具,可以在各種系統平臺將Slice語義轉化成對應的介面的代碼。比如相同的Slice文件,在X86平臺可以通過Slice2Java轉化成相應的Java介面代碼,在ARM平臺通過Slice2C++可以轉化成對應的C++介面代碼。

2、Ice.Object

Ice.Object是RPC介面的抽象,ICE中一個Object對象可以包含多個介面,每一個介面對應一個響應客戶端請求的Object實體。ICE使用(Object Identity)來區分不同的Object對象,identity在集群中必須全局唯一。

3、Proxy
Ice.Object是相對於ICE服務端來說的,而Proxy則是相對於ICE客戶端來說的.客戶端要想調用某個介面,必須持有該對象的代理,Proxy就是Object對象在客戶端的代理者。

4、Adapter
Adapter是對象適配器,用於把客戶端請求映射到某個Object對象的特定方法上。

5、IceBox

IceBox是應用容器,每個IceBox實例叫做一個Server,對應一個獨立的進程,系統為每個server分配一個獨立的server id,ICE通過對管理IceBox進程來實現負載均衡等操作。

6、IceNode
IceBox對應的獨立進程,而IceNode則對應的獨立伺服器節點,一個伺服器節點可以啟動多個IceBox進程實例。

7、IceGrid

ICE可以同時管理多個IceGrid,每個IceGrid可以理解成是一套服務的整體拓撲結構,Locator是用於定位IceGrid的定址信息。

8、Registry

服務的註冊中心,客戶端在調用介面時,需要指定主從註冊中心的地址,介面處理時首先請求註冊中心,註冊中心為其分配處理當前請求的adapter,adapter再將請求定位到具體的指定server進程中的特定object對象處理。

9、部署及運行結構

很多朋友覺得ICE複雜,可能是因為ICE提出了很多新的概念,而不清每個概念的包含關係,以至於不能理解它的運行方式,再加上資料匱乏所以難以上手。我覺得只要從兩個角度去看這個問題可能會比較清晰,一個是物理結構(伺服器節點),另一個是軟體結構(服務運行結構)。

  • 從物理節點的角度

一個IceGrid集群,包括至少一個註冊中心節點(建議線上使用主從註冊中心節點),並且一個IceGrid集群管理多個Node節點。

  • 從服務運行的角度
IceGrid集群可以啟動一個或多個應用(Application),每個應用可以占用當前IceGrid集群中的一個或多個節點,這裡的Application概念你可以理解成是我們常說的微服務。 Application啟動時其配置文件指定了當前應用運行所可以占用的節點信息,以及每個節點可以啟動的Server實例,這個Server實例就是IceBox進程。註意:application啟動時預設不會同時啟動server實例,server實例是根據客戶端請求併發量自動啟動的,當然也可以手動啟動。

為什麼IceGrid部署時明明已經啟動了對應的Node節點,但application的配置文件還需要加Node配置?
其實這個問題很好理解,Grid可以管理多個節點,所以部署時被其管理的每個節點都要啟動一個icegridnode進程。而Grid也可以包含多個application,每個application可以根據需要占用Grid所有節點中的一個或多個。

service和adapter區別?
ICE中的service對應的是介面,一個server中可以包含多個介面。
adapter是特定對象上的介面,用來將客戶端請求分配到特定server上去處理。可能有些拗口,不過我拿XL-LightHouse的進程舉一個例子就很明白了。

如上圖:
server list,將集群所有IceBox進程羅列出來。
service list,serverID將當前server中的介面名稱羅列出來。
adapter list,ICE將所有server中的每個介面實例都分配了一個adapter句柄並將其羅列出來。

四、Ice安裝

部署前請確保系統已安裝JDK、GCC等依賴包!

不同發行版的安裝方式略有不同,以下命令只適合RHEL、CentOS、Rocky和Almalinux,如果您是其他的Linux發行版,請按照官網描述的方式安裝(也可以參考XL-LightHouse源碼中的/bin/install/install_ice.sh文件)。

官網安裝參考:https://doc.zeroc.com/ice/3.7/release-notes/using-the-linux-binary-distributions
下麵以AlmaLinux安裝為例:

#註意:rpm安裝需要根據系統版本指定el版本,使用uname命令可以查看系統el版本,不能配錯
[root@VM-6-22-rockylinux ~]# uname -a
Linux VM-6-22-rockylinux 5.14.0-162.6.1.el9_1.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Nov 18 02:06:38 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

我用的Alma9.1部署時需要指定el9,安裝命令即為:
sudo yum install https://zeroc.com/download/ice/3.7/el9/ice-repo-3.7.el9.noarch.rpm
sudo yum install ice-all-runtime ice-all-devel

安裝成功後,可以查看到相關的命令:

[root@VM-6-37-almalinux soft]# ice
icebox           iceboxadmin      icegridadmin     icegridgui       icegridregistry  icepatch2client  icestormadmin    
icebox++11       icebridge        icegriddb        icegridnode      icepatch2calc    icepatch2server  icestormdb  

五、Slice文件生成

完整代碼請查閱:https://github.com/xl-xueling/ZerocICEDemo.git

(1)、創建slice文件printer.ice

[["java:package:com.dtstep.test.ice"]]
module PrinterServer {
        interface Printer{
                void printStr(string str);
        };
};

(2)、生成介面代碼

#進入到Linux環境,執行以下命令
slice2java printer.ice 

以上命令會在當前目錄生成介面代碼,因為我這裡的部署客戶端和服務端都是使用的Java語言,所以該介面代碼客戶端和服務端都需要用,如果客戶端和服務端是跨語言的需要用相應的命令生成不同的介面代碼。

(3)、創建工程並引入依賴包

<dependencies>
        <dependency>
            <groupId>com.zeroc</groupId>
            <artifactId>ice</artifactId>
            <version>3.7.9</version>
        </dependency>
        <dependency>
            <groupId>com.zeroc</groupId>
            <artifactId>icebox</artifactId>
            <version>3.7.9</version>
        </dependency>
        <dependency>
            <groupId>com.zeroc</groupId>
            <artifactId>icegrid</artifactId>
            <version>3.7.9</version>
        </dependency>
        <dependency>
            <groupId>com.zeroc</groupId>
            <artifactId>ice-compat</artifactId>
            <version>3.7.9</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.zeroc</groupId>
            <artifactId>glacier2</artifactId>
            <version>3.7.9</version>
        </dependency>
    </dependencies>

(4)、將上面生成的介面代碼拷貝到工程中。

六、本地運行模式

完整代碼請查閱:https://github.com/xl-xueling/ZerocICEDemo.git

(1)、創建服務端實現類

public class PrinterServer {

    public static void main(String[] args) {
        Communicator ic = null;
        try {
            ic = Util.initialize();
            ObjectAdapter adapter = ic.
                    createObjectAdapterWithEndpoints("PrinterServiceAdapter", "default -p 10000");
            LocalPrinterServiceImpl servant = new LocalPrinterServiceImpl();
            adapter.add(servant, Util.stringToIdentity("PrinterService"));
            adapter.activate();
            System.out.println("The server starts listening ...");
            ic.waitForShutdown();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ic != null) {
                ic.destroy();
            }
        }
    }
}

(2)、創建客戶端端實現類

public class PrinterClient {

    public static void main(String[] args) {
        Communicator ic = null;
        try {
            ic = Util.initialize();
            ObjectPrx base = ic.stringToProxy("PrinterService:default -p 10000");
            PrinterPrx proxy = PrinterPrx.checkedCast(base);
            for(int i=0;i<500;i++){
                String msg = "Hello World_" + i;
                proxy.printStr(msg);
                System.out.println("client send message,msg:" + msg);
                Thread.sleep(1000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ic != null) {
                ic.destroy();
            }
        }
    }
}

(3)、同時本地運行客戶端和服務端可以正常發送和接收消息

七、集群模式配置

註意:
1、以下操作不要在root賬號下執行,如果在root賬號下啟動icegridnode,ice啟動服務為了安全起見使用的是nobody用戶,而該用戶沒有目錄訪問許可權,所以啟動會報錯!
2、完整代碼請查閱:https://github.com/xl-xueling/ZerocICEDemo.git
3、以下內容我直接基於【XL-LightHouse開源通用型流式數據統計項目】的結構進行修改,XL-LightHouse是對程式員日常開發很有幫助的輔助工具,歡迎GitHub搜索瞭解。

(1)、集群規劃
以下操作我在三台AlmaLinux節點上部署該集群,IP分別為:

10.206.6.37 #作為註冊中心主節點和Node運算節點
10.206.6.39 #作為註冊中心從節點和Node運算節點
10.206.6.25 #作為Node運算節點

(2)、創建工程所需目錄

在三台伺服器上依次創建以下目錄結構。

#該路徑用於存儲相關配置文件
mkdir -p /opt/soft/PrinterProject/conf

#該路徑用於存儲註冊中心的數據文件及日誌信息
mkdir -p /opt/soft/PrinterProject/data/registdata
#該路徑用於存儲Node節點的運行數據文件
mkdir -p /opt/soft/PrinterProject/data/nodedata
#該路徑用於存儲Node節點的輸出日誌信息
mkdir -p /opt/soft/PrinterProject/data/nodeoutput

#創建依賴包路徑,包含工程jar包和ICE依賴包
mkdir -p /opt/soft/PrinterProject/lib

#賦予目錄讀寫許可權
chmod -R 755 /opt/soft/PrinterProject

(3)、創建註冊中心主節點配置文件 master_registry.cfg

IceGrid.InstanceName=PrinterIceGrid
IceGrid.Registry.Client.Endpoints=tcp -p 4061
IceGrid.Registry.Server.Endpoints=tcp
IceGrid.Registry.Internal.Endpoints=tcp
IceGrid.Registry.PermissionsVerifier=PrinterIceGrid/NullPermissionsVerifier
IceGrid.Registry.AdminPermissionsVerifier=PrinterIceGrid/NullPermissionsVerifier
IceGrid.Registry.LMDB.Path=/opt/soft/PrinterProject/data/registdata
IceGrid.Registry.DynamicRegistration=1
Ice.Admin.InstanceName=AdminInstance
Ice.LogFile=/opt/soft/PrinterProject/data/registdata/ice-regist.log

(4)、創建註冊中心從節點配置文件 slave_registry.cfg

Ice.Default.Locator=PrinterIceGrid/Locator:tcp -h 10.206.6.37 -p 4061
IceGrid.Registry.Client.Endpoints=tcp -p 4061
IceGrid.Registry.Server.Endpoints=tcp
IceGrid.Registry.Internal.Endpoints=tcp
IceGrid.Registry.PermissionsVerifier=PrinterIceGrid/NullPermissionsVerifier
IceGrid.Registry.AdminPermissionsVerifier=PrinterIceGrid/NullPermissionsVerifier
IceGrid.Registry.LMDB.Path=/opt/soft/PrinterProject/data/registdata
IceGrid.Registry.DynamicRegistration=1
IceGrid.Registry.ReplicaName=Replica1
Ice.LogFile=/opt/soft/PrinterProject/data/registdata/ice-regist.log

(5)、創建每台節點對應的node.cfg文件

註意:每個節點的Node.Name不可相同,而且需要與application.xml文件中的節點名稱一致。

Ice.Default.Locator=PrinterIceGrid/Locator:tcp -h 10.206.6.37 -p 4061:tcp -h 10.206.6.39 -p 4061
IceGrid.Node.Name=node1
IceGrid.Node.Endpoints=tcp
#配置文件中的路徑必須首先創建出來,並且目錄需要有寫入數據的許可權
IceGrid.Node.Data=/opt/soft/PrinterProject/data/nodedata
IceGrid.Node.Output=/opt/soft/PrinterProject/data/nodeoutput
IceGrid.Node.CollocateRegistry=0
Ice.StdErr=/opt/soft/PrinterProject/data/nodeoutput/ice_stderr.log

(6)、創建應用配置文件application.xml

<icegrid>
    <application name="PrinterServiceApplication">
        <properties id="MultiThreaded">
            <property name="Ice.PrintStackTraces" value="1"/>
            <property name="IceSSL.Trace.Security" value="2"/>
            <property name="Ice.ThreadPool.Client.Size" value="50"/>
            <property name="Ice.ThreadPool.Client.SizeMax" value="500"/>
            <property name="Ice.ThreadPool.Server.Size" value="50"/>
            <property name="Ice.ThreadPool.Serxver.SizeMax" value="500"/>
            <property name="IceBox.InheritProperties" value="1"/>
            <property name="Ice.Override.ConnectTimeout" value="2000"/>
            <property name="Ice.Override.Timeout" value="2000" />
            <property name="IceBox.Trace.ServiceObserver" value="1"/>
            <property name="Ice.Default.Timeout" value="2000"/>
            <property name="Ice.Default.LocatorCacheTimeout" value="1200" />
            <property name="Ice.BackgroundLocatorCacheUpdates" value="1"/>
        </properties>
        <server-template id="PrinterBoxTemplate">
            <parameter name="index" default="0"/>
            <icebox id="printer-icebox${index}" exe="java" activation="on-demand" >
                <properties>
                    <properties refid="MultiThreaded" />
                </properties>
                <option>-Xmx4000M</option>
                <option>-Xms4000m</option>
                <option>-XX:+UseCompressedOops</option>
                <option>-XX:+HeapDumpOnOutOfMemoryError</option>
                <option>-XX:+UseG1GC</option>
                <option>-XX:-UseBiasedLocking</option>
                <option>-XX:G1HeapRegionSize=4M</option>
                <option>com.zeroc.IceBox.Server</option>
                <env>CLASSPATH=.:/opt/soft/PrinterProject/lib/*</env>
                <!--該處配置server端的介面類地址-->
                <service name="PrinterService" entry="com.dtstep.test.ice.PrinterServer.cluster.server.PrinterService">
                    <adapter name="PrinterService" id="PrinterService${index}" endpoints="default" replica-group="PrinterServiceRep" />
                </service>
            </icebox>
        </server-template>
        <replica-group id="PrinterServiceRep">
            <load-balancing type="adaptive" n-replicas="0" />
            <!--該處的type配置slice文件的module名稱和interface名稱-->
            <object identity="PrinterServiceIdentity" type="::PrinterServer::Printer"/>
        </replica-group>
        <!--node名稱,必須與node.cfg中的名稱對應-->
        <node name="node1">
            <!--註意template名稱需要與上面的server-template保持一致 -->
            <server-instance template="PrinterBoxTemplate" index="11"/>
            <server-instance template="PrinterBoxTemplate" index="12"/>
        </node>
        <node name="node2">
            <server-instance template="PrinterBoxTemplate" index="21"/>
            <server-instance template="PrinterBoxTemplate" index="22"/>
        </node>
        <node name="node3">
            <server-instance template="PrinterBoxTemplate" index="31"/>
            <server-instance template="PrinterBoxTemplate" index="32"/>
        </node>
     </application>
</icegrid>

(7)、創建集群Server端實現

public class PrinterService implements Service  {

    @Override
    public void start(String s, Communicator communicator, String[] strings) {
        ObjectAdapter adapter = communicator.createObjectAdapter(s);
        communicator.getProperties().setProperty("Ice.MessageSizeMax", "1409600");
        ClusterPrinterServiceImpl servant = new ClusterPrinterServiceImpl();
        adapter.add(servant, Util.stringToIdentity("PrinterServiceIdentity"));
        adapter.activate();
        System.out.println("printer server start success!");
    }

    @Override
    public void stop() {

    }
}

(8)、創建集群Client端實現

public class ClientTest {

    public static void main(String[] args) {
        Communicator ic = null;
        try {
            String initParams = "--Ice.Default.Locator=PrinterIceGrid/Locator:tcp -h 10.206.6.39 -p 4061:tcp -h 10.206.6.37 -p 4061 -z";
            String [] params = new String[]{initParams};
            ic = Util.initialize(params);
            //註意該處配置與介面對應的replica-group的identity名稱保持一致
            ObjectPrx objectPrx = ic.stringToProxy("PrinterServiceIdentity").ice_connectionId(UUID.randomUUID().toString()).ice_locatorCacheTimeout(1200);
            PrinterPrx proxy = PrinterPrx.checkedCast(objectPrx);
            for(int i=0;i<500;i++){
                String msg = "Hello World_" + i;
                proxy.printStr(msg);
                System.out.println("client send message,msg:" + msg);
                Thread.sleep(1000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ic != null) {
                ic.destroy();
            }
        }
    }
}

(9)、將上述配置文件上傳到conf目錄。
(10)、將工程打包和maven依賴包上傳到lib目錄下
(11)、工程的完整文件及路徑信息如下

[root@VM-6-37-almalinux PrinterProject]# pwd
/opt/soft/PrinterProject
[root@VM-6-37-almalinux PrinterProject]# tree -a ./
./
├── conf
│   ├── application.xml
│   ├── master_registry.cfg
│   ├── node1.cfg
│   ├── node2.cfg
│   ├── node3.cfg
│   ├── printer.ice
│   └── slave_registry.cfg
├── data
│   ├── nodedata
│   ├── nodeoutput
│   └── registdata
└── lib
    ├── glacier2-3.7.9.jar
    ├── ice-3.7.9.jar
    ├── icebox-3.7.9.jar
    ├── ice-compat-3.7.9.jar
    ├── icegrid-3.7.9.jar
    └── TestICE-1.0-SNAPSHOT.jar

5 directories, 13 files

(12)、將以上工程文件夾同步到集群各個節點。

七、集群模式啟動

(1)、在第一臺伺服器上啟動註冊中心主節點

#註意:如果執行重啟操作,請檢查一下icegridregistry進程是否仍存在,如果存在先kill掉,然後務必刪除registdata目錄下的文件後再重啟。

icegridregistry --Ice.Config=/opt/soft/PrinterProject/conf/master_registry.cfg &

執行完後,查看/opt/soft/PrinterProject/data/registdata/ice-regist.log是否有異常。

(2)、在第二台伺服器上啟動註冊中心主節點,註意與主節點配置文件不同

#註意:如果重啟請檢查一下icegridregistry進程是否仍存在,如果存在kill掉,然後務必刪除registdata目錄下的文件後再重啟。

icegridregistry --Ice.Config=/opt/soft/PrinterProject/conf/slave_registry.cfg &

執行完後,查看/opt/soft/PrinterProject/data/registdata/ice-regist.log是否有異常。

(3)、在三台伺服器依次啟動節點,註意配置文件各不相同

#註意:如果重啟請檢查一下icegridnode進程是否仍存在,如果存在kill掉,並同時將nodedata目錄下文件刪除後再重啟。

icegridnode --Ice.Config=/opt/soft/PrinterProject/conf/node1.cfg &

icegridnode --Ice.Config=/opt/soft/PrinterProject/conf/node2.cfg &

icegridnode --Ice.Config=/opt/soft/PrinterProject/conf/node3.cfg &

(4)、進程檢查

執行完以上操作後,在註冊中心主節點執行

icegridadmin命令,user id和password隨便輸入進入到ICE控制台。

執行help命令,可查看所有組件,執行 node help,service help ...可查看每個組件的幫助信息。
執行node list命令,查看當前節點是否啟動正常,如果正常進行下一步。

八、啟動應用Application

執行icegridamin命令進入ICE控制台。

# 啟動應用
>> application add /opt/soft/PrinterProject/conf/application.xml

# 啟動應用後,預設不會立即啟動server,當有客戶端請求時會自動啟動server

# 查看server 列表
>> server list

# 手動啟動server,進入nodeout目錄查看日誌是否正常。
>> server start printer-icebox11

# 查看應用列表
>> application list

# 移除應用
>> application remove PrinterServiceApplication

執行cluster目錄內的ClientTest.java發送消息到服務端,服務端的nodeoutput目錄可以正常輸出日誌信息(註意:由於集群在三台伺服器上啟動了6個進程,所以需要具體看下請求被分發到了哪個進程,輸出的日誌文件是不同的,線上使用的時候可以配置log4j讓節點內的多個進程都輸出到一個日誌文件)。

[work@VM-6-25-almalinux nodeoutput]$ tail -f printer-icebox32.out 
server receive message,msg:Hello World_25
server receive message,msg:Hello World_26
server receive message,msg:Hello World_27
server receive message,msg:Hello World_28
server receive message,msg:Hello World_29
server receive message,msg:Hello World_30
server receive message,msg:Hello World_31
server receive message,msg:Hello World_32
server receive message,msg:Hello World_33
server receive message,msg:Hello World_34
server receive message,msg:Hello World_35

完整代碼及配置信息請查閱:https://github.com/xl-xueling/ZerocICEDemo.git

九、解鎖新技能、打開新世界

上述內容向大家介紹了一款超高性能的RPC服務框架ZerocICE的集群部署方式和初步使用。接下來向大家推薦一款更具有實用價值的開發好幫手XL-LightHouse。XL-LightHouse是一款通用型流式大數據統計工具,對於程式員來說,它有幾個特性:

1、世界範圍獨一無二;
2、它對各種工種的程式員都具有很大的實用價值;
3、你只要用上它,就會離不開它;

建議您花一兩分鐘的時間GitHub搜索XL-LightHouse或訪問dtstep.com瞭解更多!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ## pprof簡介 `pprof`是Go語言的一個性能分析庫,它可以幫助開發者找出程式中的性能瓶頸。`pprof`提供了CPU分析、記憶體分析、阻塞分析等多種性能分析功能。 以下是`pprof`的主要特性: 1. **CPU分析**:`pprof`可以記錄程式在CPU上的運行時間,並將這些數據以火焰 ...
  • [TOC]([Qt開發探幽(二)]淺談關於元對象,巨集和Q_ENUM) # [Qt開發探幽(二)]淺談關於元對象,巨集和Q_ENUM ## 前言 最近在開發的時候,我自己寫了一套虛函數。這也是我第一次寫這麼大一個框架,遇到了一些有點莫名其妙的問題(也不能算莫名奇妙,只能說有點玩不明白),詳情可以見 [[ ...
  • acwing學習筆記,記錄容易忘記的知識點和難題。快速排序、歸併排序、整數二分、浮點數二分、高精度運算、一維首碼和、二維首碼和、一維差分、二維差分、雙指針演算法、位運算、整數離散化、區間合併 ...
  • 使用`Matplotlib`對分析結果可視化時,比較各類分析結果是常見的場景。在這類場景之下,將多個分析結果繪製在一張圖上,可以幫助用戶方便地組合和分析多個數據集,提高數據可視化的效率和準確性。 本篇介紹`Matplotlib`繪製子圖的常用方式和技巧。 # 1. 添加子圖的方式 添加子圖主要有兩種 ...
  • 在筆者前幾篇文章中我們一直在探討如何利用`Metasploit`這個滲透工具生成`ShellCode`以及如何將ShellCode註入到特定進程內,本章我們將自己實現一個正向`ShellCode`Shell,當進程被註入後,則我們可以通過利用NC等工具連接到被註入進程內,並以對方的許可權及身份執行命令... ...
  • ![](https://img2023.cnblogs.com/other/1218593/202309/1218593-20230901100033869-964667327.png) ## **背景** 在我們平常的編碼中,通常會將一些對象保存起來,這主要考慮的是對象的創建成本。 比如像線程資源 ...
  • 今天推薦一個github的開源工具 [pkgu](https://github.com/Abeautifulsnow/pkgu),支持以表格形式展示當前python環境下的有新版本的package的版本信息,並支持全部或部分更新這些已經過期或者有新版的庫。 該工具目前還提供了 `cache` 功能, ...
  • ## 14.1、概述 ### 14.1.1、編程式事務 > 事務功能的相關操作全部通過自己編寫代碼來實現: ``` Connection conn = ...; try { // 開啟事務:關閉事務的自動提交 conn.setAutoCommit(false); // 核心操作 // 提交事務 co ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...