집 >백엔드 개발 >C#.Net 튜토리얼 >C# 메시지 큐 애플리케이션 -1
소개
Microsoft는 최근 통합 애플리케이션 생성을 위한 새로운 플랫폼인 Microsoft
.NET Framework를 출시했습니다. .그물
이 프레임워크를 통해 개발자는 프로그래밍 언어를 사용하여 웹 서비스와 애플리케이션을 신속하게 생성하고 배포할 수 있습니다. MSIL(Microsoft Intermediate Language) 및 실시간
(JIT) 컴파일러는 이러한 언어 독립적인 프레임워크를 가능하게 합니다.
C#은 간단하고 참신하며 객체 지향적이고 형식이 안전한 프로그래밍 언어입니다. .NET 활용
프레임워크
및 C#(Microsoft? Visual Basic? 및 Managed C++ 외에도)을 사용하면
사용자가 강력한 코드를 작성할 수 있습니다.
마이크로소프트 윈도우즈? 웹 애플리케이션 및 서비스. 이 기사
는 프로그래밍 언어보다는 .NET Framework 및 C#에 중점을 두고 이러한 솔루션을 제공합니다.
말. C# 언어에 대한 소개는 "C# 소개 및 개요(영어)"에서 확인할 수 있습니다.
고가용성 메시지 대기열(MSMQ)의 확장 가능한 로드 밸런싱을 위한 솔루션을 소개합니다.
솔루션 아키텍처. 이 솔루션에는 스마트 메시지 라우터로서의 Windows 서비스 개발이 포함됩니다. 이러한 솔루션은 이전에는 Microsoft에서만 사용할 수 있었습니다.
Visual C++
프로그래머는 이를 달성할 수 있으며 .NET Framework의 등장으로 이러한 상황이 바뀌었습니다. 아래 솔루션
에서 이를 확인할 수 있습니다.
.NET Framework 애플리케이션
여기에 소개된 솔루션은 여러 메시지 대기열을 처리하는 Windows 서비스입니다.
각 대기열은 여러 스레드(메시지 수신 및 처리)에 의해 처리됩니다. 핸들러가 만든다라운드 로빈 기술이나 애플리케이션 특정 값(메시지 AppSpecific 속성)을 사용하여 대상 대기열
테이블에서 메시지를 라우팅하고 메시지 속성을 사용하여 구성 요소 메서드를 호출합니다. (예제 프로세스도 이 범주에 속합니다.
상황. ) 후자의 경우 구성 요소의 요구 사항은 주어진 인터페이스 IWeb
Message를 구현하는 것입니다. 오류를 처리하려면 애플리케이션이 처리되지 않은 메시지를 오류 대기열로 보내야 합니다.
메시징 애플리케이션은 이전 ATL(액티브 템플릿 라이브러리) 애플리케이션과 구조가 유사합니다.
. Windows 서비스를 생성하려면 .NET Framework 사용자는 슬레이브를 생성하기만 하면 됩니다.
ServiceBase
(System.ServiceControl 어셈블리에서)에서 상속된 클래스입니다. .NET
프레임워크는 개체 지향적이므로 이는 놀라운 일이 아닙니다.
애플리케이션 구조
애플리케이션의 기본 클래스는 ServiceBase에서
를 상속하는 ServiceControl입니다. 따라서 OnStart 및 OnStop을 구현해야 합니다. 메서드, 선택적 OnPause 및OnContinue 메서드가 있습니다. 실제로 클래스는 정적 메서드 Main:
using System;
public class ServiceControl: ServiceBase
// 내에서 구성됩니다. 서비스 객체의 기본 진입점을 생성합니다
public static void Main()
{
ServiceBase.Run(new ServiceControl());
}
// 서비스 매개변수를 정의하는 생성 객체
{
CanPauseAndContinue = true
ServiceName = "MSDNMessageService";
AutoLog = false
}
protected 재정의 void OnStart(string[] args) {...}
protected override void OnPause() {...}
protected override void OnContinue() {...}
}
ServiceControl 클래스는 처리해야 하는 각
클래스에 의해 생성된 처리 스레드는 실제 서비스 작업을 수행합니다.
CWorker 및 CWorkerThread 클래스를 사용하는 주요 목적은 서비스 제어 시작,
중지, 일시 중지 및 계속을 확인하는 것입니다.
주문하다. 이러한 프로세스는 비차단이어야 하므로
CWorkerThread는 CWorkerThreadAppSpecific과 CWorkerThreadAppSpecific으로 구분되는 추상 클래스입니다.
CWorkerThreadRoundRobin 및 CWorkerThreadAssembly가 상속됩니다. 이 카테고리는 그렇지 않습니다.
차이점은 수신 대기열 경로가 결정되는 방식에 있음) 마지막 클래스는 메시지 속성을 사용하여 호출합니다.
컴포넌트 방식을 사용하세요.
.NET 프레임워크 내의 오류 처리는 기본 클래스 Exception을 기반으로 합니다. 시스템
에서 오류가 발생하거나 포착되면 해당 오류는 다음에서 발생해야 합니다.
Exception으로 내보낸 클래스입니다. CWorker
서비스를 계속 실행해야 하는지 여부)를 통해 기본 클래스를 확장합니다.
마지막으로 애플리케이션에는 두 가지 구조가 포함되어 있습니다. 이러한 값 유형은 작업자 프로세스 또는 스레드에 대한
런타임 매개변수를 정의하여 CWorker를 단순화하고
CWorkerThread 개체의 구조입니다. (참조 유형 클래스 대신) 값 유형
구조를 사용하면 이러한 런타임 매개변수가 (
참조 대신) 값을 유지하도록 보장합니다.
IWebMessage 인터페이스
CWorkerThread 구현 중 하나는 구성 요소 메서드를 호출하는 클래스입니다.
CWorkerThreadAssembly라는 클래스는 다음을 사용합니다.
IWebMessage 인터페이스는 서비스와 구성 요소 간의 계약을 정의합니다.
언어로 명시적으로 정의할 수 있습니다. 기음#
IWebMessage 인터페이스의
은 다음과 같이 정의됩니다.
공용 인터페이스 IWebMessage
{
WebMessageReturn 프로세스(문자열 sMessageLabel, 문자열 sMessage
Body, int
iAppSpecific);
void Release();
}
의 반환 코드는 열거형 WebMessageReturn으로 정의됩니다.
{
ReturnGood,
ReturnBad,
ReturnAbort
}
Abort는 처리를 종료하는 것을 의미합니다. 풀어 주다
메서드는 서비스가 클래스 인스턴스를 쉽게 지울 수 있는 방법을 제공합니다.
클래스 인스턴스의 소멸자는 가비지 수집 중에만 호출되므로
비용이 많이 드는 리소스(예: 데이터베이스 연결)를 소비하는 모든 클래스에는 소멸 전에 호출할 수 있는 메서드가 있는지 확인하세요.
이러한 리소스를 공개하는 것은 매우 좋은 생각입니다.
Service.Service 네임스페이스. 서비스 코드는 여러 파일에 포함되어 있지만 동일한 네임스페이스에 포함되어 있으므로 사용자는 다른 파일을 참조할 필요가 없습니다.
IWebMessage 인터페이스는 MSDNMessageService.Interface 이름에 포함되어 있으므로
공백이므로 이 인터페이스를 사용하는 스레드 클래스에는 인터페이스 네임스페이스가 있습니다.
서비스 클래스
앞서 언급했듯이 서비스의 기본 구조는 ServiceBase에서 상속받은 클래스입니다. 중요한 메소드
서비스 제어 작업에 직접적으로 해당합니다. OnStart 메서드의 목적은 CWorker 개체를 생성하고
CWorker 클래스는 CWorkerThread 개체를 생성한 다음 이 개체에 서비스 작업을 수행하는 스레드를 생성합니다.
서비스의 런타임 구성(및 CWorker 및 CWorkerThread 개체의 속성)은
xml 기반 구성 파일에서 유지 관리됩니다. 생성된 .exe 파일과 이름은 동일하지만
.cfg 접미사를 사용합니다. 구성 예는 다음과 같습니다.
〈configuration〉
〈ProcessList〉
ProcessDefinition
ProcessName="Worker1"
ProcessDesc="2개의 스레드가 있는 메시지 작업자"
ProcessType="AppSpecific"
ProcessThreads="2"
InputQueue=".private$test_load1"
ErrorQueue=".private$test_error"〉
OutputList〉
〈OutputDefinition OutputName=".private$test_out11" /〉
〈OutputDefinition OutputName=".private$test_out12" /〉
〈/OutputList〉
〈/ProcessDefinition〉
〈ProcessDefinition〉
ProcessName="Worker2"
ProcessDesc="1명의 조립 작업자
스레드"
ProcessType="어셈블리"
ProcessThreads="1"
InputQueue=".private$test_load2"
ErrorQueue=".private$test_error"〉
OutputList〉
OutputDefinition OutputName="C:MSDNMessageServiceMessage
Example.dll" /〉
OutputDefinition
OutputName="MSDNMessageService.Message
Sample.ExampleClass"/>
〈/OutputList〉
〈/ProcessDefinition〉
〈/ProcessList〉
〈/configuration〉
이 정보에 대한 액세스는 System.Configuration 어셈블리의 Config
Manager 클래스를 통해 관리됩니다. 공전
Get 메서드는 개별 속성을 얻기 위해 열거되는 정보 컬렉션을 반환합니다. 이러한 속성 집합의 설정에 따라 도우미 개체의 런타임 특성이 결정됩니다. 이
구성 파일 외에도 정의도 생성해야 합니다.
XML 파일 구조의 메타파일 및 참조
서버 machine.cfg 구성 파일에 있는 메타파일:
〈MetaData xmlns ="x-schema :CatMeta.xms"〉
〈DatabaseMeta InternalName="MessageService"〉
ServerWiring
Interceptor="Core_XMLInterceptor"/〉
〈컬렉션
InternalName="프로세스" PublicName="프로세스 목록"
PublicRowName="프로세스 정의"
SchemaGeneratorFlags="EMITXMLSCHEMA"〉
Flags="PRIMARYKEY" />
Property InternalName="ProcessDesc" Type="String" />
Property
InternalName="ProcessType" Type="Int32" 기본값
Value="RoundRobin" 〉
〈Enum InternalName="RoundRobin" Value="0"/〉
〈Property InternalName="ProcessThreads"
Type="Int32"
DefaultValue="1" /〉
속성
InternalName="ErrorQueue" Type="String" /〉
속성
InternalName="OutputName" Type="String" />
Operator="EQUAL" /〉
〈/Collection〉
Collection
InternalName="Output"
PublicName="OutputList"
PublicRowName="OutputDefinition"
SchemaGeneratorFlags="EMITXMLSCHEMA"〉
Flags="PRIMARYKEY" />
Property InternalName="OutputName" Type="String" 메타
Flags="PRIMARYKEY" /〉
QueryMeta InternalName="All"
MetaFlags="ALL" /〉
〈QueryMeta InternalName="QueryByFile"
CellName="__FILE"
Operator="EQUAL" /〉
〈/Collection〉
〈/DatabaseMeta〉
RelationMeta
PrimaryTable="프로세스"
PrimaryColumns="프로세스 이름"
ForeignTable="출력" ForeignColumns="프로세스 이름"
MetaFlags="USECONTAINMENT"/〉
〈/MetaData>
Hashtable 컬렉션은 유형 객체 name/을 보유하는 데 사용됩니다.
숫자 쌍의 목록입니다. Hashtable은
열거형만 지원하는 것이 아니라 키워드로 값을 쿼리할 수도 있습니다. 애플리케이션에서는 XML 프로세스 이름
이 유일한 키워드입니다.
비공개 Hashtable htWorkers = new Hashtable()
IConfigCollection;
cWorkers = ConfigManager.Get("ProcessList", new
AppDomainSelector());
foreach(cWorkers의 IConfigItem ciWorker)
{
WorkerFormatter
sfWorker = 새로운 WorkerFormatter()
sfWorker.ProcessName =
(string)ciWorker["ProcessName"]
sfWorker.ProcessDesc =
(문자열)ciWorker["ProcessDesc"]
sfWorker.NumberThreads =
(int)ciWorker["ProcessThreads"]
sfWorker.InputQueue =
(string)ciWorker["InputQueue"]
sfWorker.ErrorQueue =
(문자열)ciWorker["ErrorQueue"]
// 计算并定义进程类型
스위치 ((int)ciWorker["ProcessType"])
{
case 0:
sfWorker.ProcessType = WorkerFormatter.SFProcessType.
프로세스라운드로빈;
휴식;
사례 1:
sfWorker.ProcessType
= WorkerFormatter.SFProcessType.
ProcessAppSpecific;
휴식;
사례 2:
sfWorker.ProcessType = WorkerFormatter.SFProcessType.
프로세스어셈블리;
휴식;
기본값:
새 항목 던지기
Exception("알 수 없는 처리 유형");
}
// 执行更多的工作以读取输流信息
string sProcessName = (string)ciWorker["ProcessName"];
만약
(htWorkers.ContainsKey(sProcessName))
새 항목 던지기
ArgumentException("프로세스 이름은 고유해야 합니다: "
+ sProcessName);
htWorkers.Add(sProcessName, new CWorker(sfWorker));
}
는 这段代码中没有包含的主要信息是输流数据的获取。项.该信息是俇如下的简单查询读取的:
sfWorker.ProcessName + " AND 선택기=appdomain://";
ConfigQuery QQuery = 새로운 ConfigQuery(sQuery);
IConfigCollection cOutputs = ConfigManager.Get("OutputList",
qQuery);
int iSize = cOutputs.Count, iLoop = 0;
sfWorker.OutputName = 신규
문자열[iSize];
foreach(cOutput의 IConfigItem ciOutput)
sfWorker.OutputName[iLoop++] = (문자열)ciOutput["OutputName"];
제조 작업 Ashtable중용了每一个
CWorker对象,因此需
要枚举 Hashtable의 제품을 사용하여 foreach(CWorker cWorker in
htWorkers.Values)
cWorker.Start();
类似地, 实现의 OnPause、OnContinue 및 OnStop 메서드
CWorker 类
CWorker 类的主要功能是创建和管리 CWorkerThread对象。Start 、
Stop、Pause 和 Continue CWorkerThread 방식을 사용하는 방법은CWorkerThread를 시작하는 방법 중 하나입니다. Hashtable을 사용하는 방법