集群部署專題之二:超高性能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
  • PasteSpider是什麼? 一款使用.net編寫的開源的Linux容器部署助手,支持一鍵發佈,平滑升級,自動伸縮, Key-Value配置,項目網關,環境隔離,運行報表,差量升級,私有倉庫,集群部署,版本管理等! 30分鐘上手,讓開發也可以很容易的學會在linux上部署你得項目! [從需求角度介 ...
  • SQLSugar是什麼 **1. 輕量級ORM框架,專為.NET CORE開發人員設計,它提供了簡單、高效的方式來處理資料庫操作,使開發人員能夠更輕鬆地與資料庫進行交互 2. 簡化資料庫操作和數據訪問,允許開發人員在C#代碼中直接操作資料庫,而不需要編寫複雜的SQL語句 3. 支持多種資料庫,包括但 ...
  • 在C#中,經常會有一些耗時較長的CPU密集型運算,因為如果直接在UI線程執行這樣的運算就會出現UI不響應的問題。解決這類問題的主要途徑是使用多線程,啟動一個後臺線程,把運算操作放在這個後臺線程中完成。但是原生介面的線程操作有一些難度,如果要更進一步的去完成線程間的通訊就會難上加難。 因此,.NET類 ...
  • 一:背景 1. 講故事 前些天有位朋友在微信上丟了一個崩潰的dump給我,讓我幫忙看下為什麼出現了崩潰,在 Windows 的事件查看器上顯示的是經典的 訪問違例 ,即 c0000005 錯誤碼,不管怎麼說有dump就可以上windbg開幹了。 二:WinDbg 分析 1. 程式為誰崩潰了 在 Wi ...
  • CSharpe中的IO+NPOI+序列化 文件文件夾操作 學習一下常見的文件、文件夾的操作。 什麼是IO流? I:就是input O:就是output,故稱:輸入輸出流 將數據讀入記憶體或者記憶體輸出的過程。 常見的IO流操作,一般說的是[記憶體]與[磁碟]之間的輸入輸出。 作用 持久化數據,保證數據不再 ...
  • C#.NET與JAVA互通之MD5哈希V2024 配套視頻: 要點: 1.計算MD5時,SDK自帶的計算哈希(ComputeHash)方法,輸入輸出參數都是byte數組。就涉及到字元串轉byte數組轉換時,編碼選擇的問題。 2.輸入參數,字元串轉byte數組時,編碼雙方要統一,一般為:UTF-8。 ...
  • CodeWF.EventBus,一款靈活的事件匯流排庫,實現模塊間解耦通信。支持多種.NET項目類型,如WPF、WinForms、ASP.NET Core等。採用簡潔設計,輕鬆實現事件的發佈與訂閱。通過有序的消息處理,確保事件得到妥善處理。簡化您的代碼,提升系統可維護性。 ...
  • 一、基本的.NET框架概念 .NET框架是一個由微軟開發的軟體開發平臺,它提供了一個運行時環境(CLR - Common Language Runtime)和一套豐富的類庫(FCL - Framework Class Library)。CLR負責管理代碼的執行,而FCL則提供了大量預先編寫好的代碼, ...
  • 本章將和大家分享在ASP.NET Core中如何使用高級客戶端NEST來操作我們的Elasticsearch。 NEST是一個高級別的Elasticsearch .NET客戶端,它仍然非常接近原始Elasticsearch API的映射。所有的請求和響應都是通過類型來暴露的,這使得它非常適合快速上手 ...
  • 參考delphi的代碼更改為C# Delphi 檢測密碼強度 規則(仿 google) 仿 google 評分規則 一、密碼長度: 5 分: 小於等於 4 個字元 10 分: 5 到 7 字元 25 分: 大於等於 8 個字元 二、字母: 0 分: 沒有字母 10 分: 全都是小(大)寫字母 20 ...