>  기사  >  백엔드 개발  >  C# 메시지 큐 애플리케이션 -1

C# 메시지 큐 애플리케이션 -1

黄舟
黄舟원래의
2016-12-17 16:56:311519검색

소개

Microsoft는 최근 통합 애플리케이션 생성을 위한 새로운 플랫폼인 Microsoft
.NET Framework를 출시했습니다. .그물 이 프레임워크를 통해 개발자는 프로그래밍 언어를 사용하여 웹 서비스와 애플리케이션을 신속하게 생성하고 배포할 수 있습니다. MSIL(Microsoft Intermediate Language) 및 실시간
(JIT) 컴파일러는 이러한 언어 독립적인 프레임워크를 가능하게 합니다.

.NET 프레임워크와 동시에 새로운 프로그래밍 언어 C#("C 샤프"로 발음)도 있습니다.

C#은 간단하고 참신하며 객체 지향적이고 형식이 안전한 프로그래밍 언어입니다. .NET 활용 프레임워크
및 C#(Microsoft? Visual Basic? 및 Managed C++ 외에도)을 사용하면
사용자가 강력한 코드를 작성할 수 있습니다. 마이크로소프트 윈도우즈? 웹 애플리케이션 및 서비스. 이 기사
는 프로그래밍 언어보다는 .NET Framework 및 C#에 중점을 두고 이러한 솔루션을 제공합니다.
말. C# 언어에 대한 소개는 "C# 소개 및 개요(영어)"에서 확인할 수 있습니다.

최근 기사 "MSMQ: 확장 가능한 고가용성 로드 밸런싱 솔루션(영문)"

고가용성 메시지 대기열(MSMQ)의 확장 가능한 로드 밸런싱을 위한 솔루션을 소개합니다.
솔루션 아키텍처. 이 솔루션에는 스마트 메시지 라우터로서의 Windows 서비스 개발이 포함됩니다. 이러한 솔루션은 이전에는 Microsoft에서만 사용할 수 있었습니다. Visual C++
프로그래머는 이를 달성할 수 있으며 .NET Framework의 등장으로 이러한 상황이 바뀌었습니다. 아래 솔루션
에서 이를 확인할 수 있습니다.

.NET Framework 애플리케이션

여기에 소개된 솔루션은 여러 메시지 대기열을 처리하는 Windows 서비스입니다.

각 대기열은 여러 스레드(메시지 수신 및 처리)에 의해 처리됩니다. 핸들러가 만든다

라운드 로빈 기술이나 애플리케이션 특정 값(메시지 AppSpecific 속성)을 사용하여 대상 대기열
테이블에서 메시지를 라우팅하고 메시지 속성을 사용하여 구성 요소 메서드를 호출합니다. (예제 프로세스도 이 범주에 속합니다.
상황. ) 후자의 경우 구성 요소의 요구 사항은 주어진 인터페이스 IWeb
Message를 구현하는 것입니다. 오류를 처리하려면 애플리케이션이 처리되지 않은 메시지를 오류 대기열로 보내야 합니다.

메시징 애플리케이션은 이전 ATL(액티브 템플릿 라이브러리) 애플리케이션과 구조가 유사합니다.

이들 사이의 주요 차이점은 서비스를 관리하는 데 사용되는 코드와 .NET Framework 구성 요소의 사용을 캡슐화한다는 것입니다

. Windows 서비스를 생성하려면 .NET Framework 사용자는 슬레이브를 생성하기만 하면 됩니다. ServiceBase
(System.ServiceControl 어셈블리에서)에서 상속된 클래스입니다. .NET
프레임워크는 개체 지향적이므로 이는 놀라운 일이 아닙니다.

애플리케이션 구조

애플리케이션의 기본 클래스는 ServiceBase에서

를 상속하는 ServiceControl입니다. 따라서 OnStart 및 OnStop을 구현해야 합니다. 메서드, 선택적 OnPause 및

OnContinue 메서드가 있습니다. 실제로 클래스는 정적 메서드 Main:

using System;

using System.ServicePROcess;


public class ServiceControl: ServiceBase

{

// 내에서 구성됩니다. 서비스 객체의 기본 진입점을 생성합니다
public static void Main()
{
  ServiceBase.Run(new ServiceControl());
  }

  // 서비스 매개변수를 정의하는 생성 객체

  public ServiceControl()

  {
CanPauseAndContinue = true
ServiceName = "MSDNMessageService";
 AutoLog = false
}

protected 재정의 void OnStart(string[] args) {...}

protected override void OnStop() {...}

protected override void OnPause() {...}
protected override void OnContinue() {...}
}

ServiceControl 클래스는 처리해야 하는 각

메시지 대기열에 대해 일련의 CWorker 개체를 생성합니다. CWorker 클래스의 인스턴스입니다. 정의에 있는 대기열을 처리하는 데 필요한 스레드 수에 따라 CWorker 클래스는 일련의 스레드를 생성합니다. CWorkerThread 객체. CWorkerThread

클래스에 의해 생성된 처리 스레드는 실제 서비스 작업을 수행합니다.

CWorker 및 CWorkerThread 클래스를 사용하는 주요 목적은 서비스 제어 시작,
중지, 일시 중지 및 계속을 확인하는 것입니다. 주문하다. 이러한 프로세스는 비차단이어야 하므로

명령 작업은 궁극적으로 백그라운드 처리 스레드에서 실행됩니다.


CWorkerThread는 CWorkerThreadAppSpecific과 CWorkerThreadAppSpecific으로 구분되는 추상 클래스입니다.
CWorkerThreadRoundRobin 및 CWorkerThreadAssembly가 상속됩니다. 이 카테고리는 그렇지 않습니다.

같은 방식으로 메시지를 처리합니다. 처음 두 클래스는 메시지를 다른 대기열로 보내 메시지를 처리하고(

차이점은 수신 대기열 경로가 결정되는 방식에 있음) 마지막 클래스는 메시지 속성을 사용하여 호출합니다.
컴포넌트 방식을 사용하세요.

 .NET 프레임워크 내의 오류 처리는 기본 클래스 Exception을 기반으로 합니다. 시스템
에서 오류가 발생하거나 포착되면 해당 오류는 다음에서 발생해야 합니다. Exception으로 내보낸 클래스입니다. CWorker

ThreadException 클래스는 추가 속성을 첨부하여 구현된 것 중 하나입니다(정의하는 데 사용됨).

서비스를 계속 실행해야 하는지 여부)를 통해 기본 클래스를 확장합니다.

마지막으로 애플리케이션에는 두 가지 구조가 포함되어 있습니다. 이러한 값 유형은 작업자 프로세스 또는 스레드에 대한
런타임 매개변수를 정의하여 CWorker를 단순화하고 CWorkerThread 개체의 구조입니다. (참조 유형 클래스 대신) 값 유형
구조를 사용하면 이러한 런타임 매개변수가 (
참조 대신) 값을 유지하도록 보장합니다.

IWebMessage 인터페이스

 CWorkerThread 구현 중 하나는 구성 요소 메서드를 호출하는 클래스입니다.
CWorkerThreadAssembly라는 클래스는 다음을 사용합니다. IWebMessage 인터페이스는 서비스와 구성 요소 간의 계약을 정의합니다.

현재 버전의 Microsoft Visual Studio를 사용하시나요? 이와 달리 C# 인터페이스는 IDL 파일을 생성하고 컴파일할 필요 없이 모든

언어로 명시적으로 정의할 수 있습니다. 기음# IWebMessage 인터페이스의
은 다음과 같이 정의됩니다.
공용 인터페이스 IWebMessage
{
WebMessageReturn 프로세스(문자열 sMessageLabel, 문자열 sMessage
  Body, int iAppSpecific);
void Release();
}

메시지 처리를 위해 ATL 코드의 Process 메서드가 지정됩니다. Process 메서드

의 반환 코드는 열거형 WebMessageReturn으로 정의됩니다.

public enum WebMessageReturn

{
ReturnGood,
ReturnBad,
ReturnAbort
}

열거형의 정의는 다음과 같습니다. Good은 처리를 계속하는 것을 의미하고 Bad는 메시지를 오류 대기열에 쓰는 것을 의미하며

Abort는 처리를 종료하는 것을 의미합니다. 풀어 주다 메서드는 서비스가 클래스 인스턴스를 쉽게 지울 수 있는 방법을 제공합니다.
클래스 인스턴스의 소멸자는 가비지 수집 중에만 호출되므로
비용이 많이 드는 리소스(예: 데이터베이스 연결)를 소비하는 모든 클래스에는 소멸 전에 호출할 수 있는 메서드가 있는지 확인하세요.
이러한 리소스를 공개하는 것은 매우 좋은 생각입니다.

네임스페이스

네임스페이스에 대해 간략하게 소개합니다. 네임스페이스를 사용하면 애플리케이션을 내부 및 외부 표현 모두에서 논리적 요소로 구성할 수 있습니다. 서비스 내의 모든 코드는 MSDNMessage에 포함되어 있습니다.

Service.Service 네임스페이스. 서비스 코드는 여러 파일에 포함되어 있지만 동일한 네임스페이스에 포함되어 있으므로 사용자는 다른 파일을 참조할 필요가 없습니다.

IWebMessage 인터페이스는 MSDNMessageService.Interface 이름에 포함되어 있으므로
공백이므로 이 인터페이스를 사용하는 스레드 클래스에는 인터페이스 네임스페이스가 있습니다.

서비스 클래스

애플리케이션의 목적은 메시지 대기열을 모니터링하고 처리하는 것입니다. 각 대기열은 메시지를 수신할 때 서로 다른 프로세스를 실행합니다. 응용 프로그램은 Windows 서비스로 구현됩니다.

ServiceBase 클래스


앞서 언급했듯이 서비스의 기본 구조는 ServiceBase에서 상속받은 클래스입니다. 중요한 메소드

에는 OnStart, OnStop, OnPause 및 OnContinue에서 각 대체 방법은

서비스 제어 작업에 직접적으로 해당합니다. OnStart 메서드의 목적은 CWorker 개체를 생성하고

CWorker 클래스는 CWorkerThread 개체를 생성한 다음 이 개체에 서비스

작업을 수행하는 스레드를 생성합니다.

서비스의 런타임 구성(및 CWorker 및 CWorkerThread 개체의 속성)은
xml 기반 구성 파일에서 유지 관리됩니다. 생성된 .exe 파일과 이름은 동일하지만
.cfg 접미사를 사용합니다. 구성 예는 다음과 같습니다.

〈?xml version="1.0"?〉

〈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 구성 파일에 있는 메타파일:

〈?xml version ="1.0"?〉

〈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〉
  〈Property InternalName="ProcessThreads" Type="Int32"
 DefaultValue="1" /〉
   속성 InternalName="ErrorQueue" Type="String" /〉
  속성 InternalName="OutputName" Type="String" />
   〈QueryMeta InternalName="QueryByFile" CellName="__FILE"
 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>

Service 클래스는 생성된 보조 객체 목록을 유지해야 하므로

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));
}

  는 这段代码中没有包含的主要信息是输流数据的获取。项.该信息是俇如下的简单查询读取的:

string sQuery = "SELECT * FROM OutputList WHERE ProcessName=" +

  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"];

  CWorkerThread 및 Cworker类share 根据服务控

제조 작업 Ashtable중용了每一个 CWorker对象,因此需
要枚举 Hashtable의 제품을 사용하여 foreach(CWorker cWorker in htWorkers.Values)
  cWorker.Start();

  类似地, 实现의 OnPause、OnContinue 및 OnStop 메서드

CWorker는 상호 작용 방식으로 작동합니다.


CWorker 类

  CWorker 类的主要功能是创建和管리 CWorkerThread对象。Start 、

Stop、Pause 和 Continue CWorkerThread 방식을 사용하는 방법은

CWorkerThread를 시작하는 방법 중 하나입니다. Hashtable을 사용하는 방법


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.