集群部署專題之二:超高性能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 微服務框架,幫助我們輕鬆構建和管理微服務應用。 本框架不僅支持 Consul 服務註 ...
  • 先看一下效果吧: 如果不會寫動畫或者懶得寫動畫,就直接交給Blend來做吧; 其實Blend操作起來很簡單,有點類似於在操作PS,我們只需要設置關鍵幀,滑鼠點來點去就可以了,Blend會自動幫我們生成我們想要的動畫效果. 第一步:要創建一個空的WPF項目 第二步:右鍵我們的項目,在最下方有一個,在B ...
  • Prism:框架介紹與安裝 什麼是Prism? Prism是一個用於在 WPF、Xamarin Form、Uno 平臺和 WinUI 中構建鬆散耦合、可維護和可測試的 XAML 應用程式框架 Github https://github.com/PrismLibrary/Prism NuGet htt ...
  • 在WPF中,屏幕上的所有內容,都是通過畫筆(Brush)畫上去的。如按鈕的背景色,邊框,文本框的前景和形狀填充。藉助畫筆,可以繪製頁面上的所有UI對象。不同畫筆具有不同類型的輸出( 如:某些畫筆使用純色繪製區域,其他畫筆使用漸變、圖案、圖像或繪圖)。 ...
  • 前言 嗨,大家好!推薦一個基於 .NET 8 的高併發微服務電商系統,涵蓋了商品、訂單、會員、服務、財務等50多種實用功能。 項目不僅使用了 .NET 8 的最新特性,還集成了AutoFac、DotLiquid、HangFire、Nlog、Jwt、LayUIAdmin、SqlSugar、MySQL、 ...
  • 本文主要介紹攝像頭(相機)如何採集數據,用於類似攝像頭本地顯示軟體,以及流媒體數據傳輸場景如傳屏、視訊會議等。 攝像頭採集有多種方案,如AForge.NET、WPFMediaKit、OpenCvSharp、EmguCv、DirectShow.NET、MediaCaptre(UWP),網上一些文章以及 ...
  • 前言 Seal-Report 是一款.NET 開源報表工具,擁有 1.4K Star。它提供了一個完整的框架,使用 C# 編寫,最新的版本採用的是 .NET 8.0 。 它能夠高效地從各種資料庫或 NoSQL 數據源生成日常報表,並支持執行複雜的報表任務。 其簡單易用的安裝過程和直觀的設計界面,我們 ...
  • 背景需求: 系統需要對接到XXX官方的API,但因此官方對接以及管理都十分嚴格。而本人部門的系統中包含諸多子系統,系統間為了穩定,程式間多數固定Token+特殊驗證進行調用,且後期還要提供給其他兄弟部門系統共同調用。 原則上:每套系統都必須單獨接入到官方,但官方的接入複雜,還要官方指定機構認證的證書 ...
  • 本文介紹下電腦設備關機的情況下如何通過網路喚醒設備,之前電源S狀態 電腦Power電源狀態- 唐宋元明清2188 - 博客園 (cnblogs.com) 有介紹過遠程喚醒設備,後面這倆天瞭解多了點所以單獨加個隨筆 設備關機的情況下,使用網路喚醒的前提條件: 1. 被喚醒設備需要支持這WakeOnL ...
  • 前言 大家好,推薦一個.NET 8.0 為核心,結合前端 Vue 框架,實現了前後端完全分離的設計理念。它不僅提供了強大的基礎功能支持,如許可權管理、代碼生成器等,還通過採用主流技術和最佳實踐,顯著降低了開發難度,加快了項目交付速度。 如果你需要一個高效的開發解決方案,本框架能幫助大家輕鬆應對挑戰,實 ...