Posts Tagged WCF

Kiểm soát truy cập với WCF Throttling

Dịch vụ của bạn có thể bị quá tải khi số người sử dụng tăng đột biến. Thật không may, các hệ thống phần mềm thường không thích nghi tốt trong những trường hợp như thế này. Kịch bản xấu nhất là toàn hệ thống bị crash dẫn đến việc gián đoạn dịch vụ, gây khó chịu cho cả nhà cung cấp lẫn người sử dụng! Để tránh rơi vào tình huống trên, WCF cung cấp một cơ chế cho phép kiểm soát lượng truy cập đến dịch vụ và giới hạn số kết nối tối đa. Tính năng đó gọi là Throttling.

Cấu hình WCF Throttling

Cũng như nhiều tính năng khác, Throttling cho phép bạn cấu hình bằng hai cách: khai báo trong file config hoặc bằng lập trình trong code. Ví dụ sau minh họa cách cấu hình theo kiểu khai báo sử dụng thẻ <serviceThrottling> trong phần <serviceBehaviors>

<system.serviceModel>
   <services>
      <service name="ThrottledService" behaviorConfiguration="ThrottlingDemo">
         ...
      </service>
   </services>
   <behaviors>
      <serviceBehaviors>
         <behavior name="ThrottlingDemo">
            <serviceThrottling
               maxConcurrentCalls="100"
               maxConcurrentSessions="5000"
               maxConcurrentInstances="5100" />
         </behavior>
      </serviceBehaviors>
   </behaviors>
</system.serviceModel>

Thẻ <serviceThrottling> có 3 thuộc tính quan trọng sau:

  • maxConcurrentCalls: số yêu cầu tối đa đồng thời. Thuộc tính này giới hạn tổng số yêu cầu có thể được xử lý tại một thời điểm. Trong .NET Framework 3.0, giá trị này mặc định là 16. Tuy nhiên con số này là quá thấp trong nhiều trường hợp thực tế dẫn đến việc các nhà quản trị thường xuyên phải cấu hình lại. Vì vậy WCF4 đã thay đổi giá trị mặc định này thành 16 x ProcessorCount (16 x số bộ vi xử lý trên máy).
  • maxConcurrentSessions: số kết nối có session tối đa. Giá trị mặc định là 10 (WCF3) và 100 x ProcessorCount (WCF4).
  • maxConcurrentInstances: số đối tượng InstanceContext tối đa. Con số này sẽ tương đương với tổng số session nếu InstanceContextMode là PerSession hoặc tổng số lời gọi dịch vụ đồng thời nếu InstanceContextMode là PerCall. Giá trị mặc định bằng tổng giá trị của maxConcurrentCalls và maxConcurrentSessions.

Tương tự, ta cũng có thể thực hiện cấu hình Throttling trong code. Một lưu ý nhỏ là các thiết lập bằng code sẽ ghi đè các thiết lập trong file config trong trường hợp cả hai thiết lập này cùng tồn tại. Việc cấu hình trong code được thực hiện thông qua property Behaviors của lớp ServiceDescription:

ServiceHost host = new ServiceHost(typeof(ThrottledService));
ServiceThrottlingBehavior throttlingBehavior =
   host.Description.Behaviors.Find<ServiceThrottlingBehavior>(  );
if(throttlingBehavior == null)
{
   throttlingBehavior = new ServiceThrottlingBehavior(  );
   throttlingBehavior.MaxConcurrentCalls = 100;
   throttlingBehavior.MaxConcurrentSessions = 5000;
   throttlingBehavior.MaxConcurrentInstances = 5100;
   host.Description.Behaviors.Add(throttlingBehavior);
}

host.Open(  );

Đoạn code trên kiểm tra xem đối tượng ServiceThrottlingBehavior có tồn tại hay chưa. Nếu chưa có, một đối tượng mới được tạo và thiết lập các giá trị cần thiết. Nhớ rằng bạn cần phải thực hiện cấu hình trước khi gọi phương thức Open() của ServiceHost.

Ngoài ra, nếu bạn sử dụng TCP hoặc IPC binding, bạn còn có thể chỉ định số kết nối tối đa cho từng Endpoint của binding đó với property MaxConnections của lớp NetTcpBinding hoặc NetNamedPipeBinding. Sau đây là cách cấu hình trong file config (đương nhiên là bạn cũng có thể cấu hình trong code như ở trên):

<bindings>
   <netTcpBinding>
      <binding name="TCP" maxConnections="30"/>
   </netTcpBinding>
</bindings>

Nhận xét

Throttling bảo vệ dịch vụ khỏi nguy cơ bị vắt kiệt tài nguyên vào những lúc cao điểm bằng cách ngưng xử lý các yêu cầu một khi hệ thống vượt quá mức giới hạn cho phép. Các yêu cầu này không bị từ chối mà được đưa vào hàng đợi chờ đến lượt mình được xử lý. Tuy nhiên nếu thời gian chờ quá dài thì phía client có thể sẽ gặp phải TimeoutException.

Throttling không phải là liều thuốc thần làm tăng năng suất hệ thống. Trên thực tế, Throttling chỉ có tác dụng khi sự gia tăng số lượng client là đột biến và nhất thời. Nó sẽ trở nên vô dụng nếu hệ thống bị quá tải thường xuyên và kéo dài. Trong trường hợp đó, bạn nên nghĩ đến việc nâng cấp hoặc thiết kế lại hệ thống cho phù hợp với nhu cầu sử dụng cao hơn.

,

Để lại phản hồi

Bảo mật trong WCF: Cấu hình WCF audit

WCF Audit

WCF cung cấp một tính năng bảo mật hữu ích gọi là audit, cho phép ghi lại các sự kiện xảy ra vào trong Windows Event để tiện cho việc khảo sát sau này. Đây là một công cụ đáng giá cho cả các lập trình viên và các nhà quản trị hệ thống để chẩn đoán và xử lý các vấn đề liên quan đến bảo mật. Audit trong WCF có thể thực hiện ở hai cấp độ sau:

  • Cấp dịch vụ (service level): khi người gọi dịch vụ được cấp quyền truy cập.
  • Cấp thông điệp (message level): khi WCF kiểm tra tính hợp lệ của thông điệp và chứng thực người gọi.

Quá trình audit được điều khiển bởi lớp ServiceSecurityAuditBehavior. Lớp này có giao diện như sau:

public sealed class ServiceSecurityAuditBehavior : IServiceBehavior
{
     public AuditLogLocation AuditLogLocation   {get;set;}
     public AuditLevel MessageAuthenticationAuditLevel   {get;set;}
     public AuditLevel ServiceAuthorizationAuditLevel   {get;set;}
     // Các thành viên khác
}

Lớp ServiceSecurityAuditBehavior có các property MessageAuthenticationAuditLevel và ServiceAuthorizationAuditLevel để kiểm soát việc audit ở từng cấp độ. Giá trị của hai property này được quy định trong enum AuditLevel:

public enum AuditLevel
{
     None,
     Success,
     Failure,
     SuccessOrFailure
}

Mặc định, cả hai property trên đều mang giá trị None (không audit). Chúng ta có thể thiết lập các giá trị khác tùy theo nhu cầu: Success (chỉ ghi lại những sự kiện thành công), Failure (chỉ ghi lại những sự kiện thất bại) hoặc SuccessOrFailure. Nếu bạn chỉ quan tâm đến các sự kiện thất bại, bạn có thể chọn Failure (thay vì SuccessOrFailure) để tăng tốc độ. Tuy nhiên, việc ghi lại cả các sự kiện Success đôi lúc sẽ có ích trong việc chẩn đoán nguyên nhân.

Một property khác là AuditLogLocation, xác định nơi chứa các thông tin audit. Các giá trị của property này được quy định trong enum tương ứng:

public enum AuditLogLocation
{
     Default,
     Application,
     Security
}

Giá trị mặc định là Default, quyết định nơi lưu trữ tùy vào hệ điều hành. Hai giá trị còn lại cho phép ghi thông tin audit vào application log (Application) hoặc security log (Security).

Sử dụng WCF audit

Tính năng audit có thể được cấu hình và kích hoạt bằng lập trình hoặc bằng cách khai báo trong file config. Ví dụ sau minh họa cách thực hiện việc này trong file config của ứng dụng, bằng cách thêm một tag <behavior> trong phần khai báo các behavior.

<behaviors>
   <behavior name="SecurityAudit">
      <serviceSecurityAudit auditLogLocation="Default"
            suppressAuditFailure="true"
            serviceAuthorizationAuditLevel="None"
            messageAuthenticationAuditLevel="SuccessOrFailure" />
      </behavior>
</behaviors>

Các thuộc tính quan trọng của behavior này được khai báo trong tag <serviceSecurityAudit>. Bạn có thể nhận ra một thuộc tính mới là suppressAuditFailure với giá trị mặc định là true, cho phép bỏ qua các lỗi trong quá trình audit. Ngược lại giá trị false sẽ làm phát sinh exception, có thể hữu ích trong debug. Giá trị true được khuyến cáo khi vận hành ứng dụng thực tế để tăng tính bảo mật. Sau khi cấu hình xong, ta cần phải tham chiếu đến behavior này trong phần khai báo service. (Lưu ý thay TypeName bằng tên lớp service của bạn)

<services>
    <service type="TypeName" behaviorConfiguration="SecurityAudit">
    ...
    </service>
</services>

Tương tự, sau đây là cách thực hiện cùng tác vụ trên trong code:

// tạo behavior và cấu hình các thuộc tính
ServiceSecurityAuditBehavior audit = new ServiceSecurityAuditBehavior();
audit.AuditLogLocation = AuditLogLocation.Default;
audit.MessageAuthenticationAuditLevel = AuditLevel.SuccessOrFailure;
audit.ServiceAuthorizationAuditLevel = AuditLevel.None;
audit.SuppressAuditFailure = true;
// Gỡ bỏ behavior cũ và thêm behavior mới tạo
serviceHost.Description.Behaviors.Remove<ServiceSecurityAuditBehavior>();
serviceHost.Description.Behaviors.Add(audit);

Tham khảo: http://msdn.microsoft.com/en-us/library/ms734737.aspx

, ,

Để lại phản hồi

Follow

Get every new post delivered to your Inbox.