Wednesday, May 29, 2013

How to find the culprit when CPU starts to spin?




When your JAVA process started to spin your CPU, you need to immediately issue following two commands and get the invaluable information required to tackle the issue.

1. jstack <pid> > thread-dump.txt
2. ps -C java -L -o pcpu,cpu,nice,state,cputime,pid,tid > thread-usage.txt

After getting those two files, what you can do is,

1. find the thread ID (which belongs to the corresponding PID ) which takes the highest CPU usage by examine thread-usage.txt file.

%CPU CPU  NI S     TIME   PID   TID
..........
  0.0   -   0 S 00:00:00  1519  1602
  0.0   -   0 S 00:00:00  1519  1603
24.8   -   0 R 00:06:19  1519  1604
  2.4   -   0 S 00:00:37  1519  1605
  0.0   -   0 S 00:00:00  1519  1606
..........


2. convert the decimal value (in this case 1604) to hexadecimal - (online converter - http://easycalculation.com/decimal-converter.php)

Hex - 644



3. search for the hexadecimal obtained (in this case 644) in the thread-dump.txt (thread-dump.txt should have that value as a thread id of one thread) and that is the thread which spins.
4. that thread usually has a stack trace, and that's the lead to find the culprit.

In this case the stack trace of the thread that spins is:

"HTTPS-Sender I/O dispatcher-1" prio=10 tid=0x00007fb54c010000 nid=0x644 runnable [0x00007fb534e20000]
   java.lang.Thread.State: RUNNABLE
        at org.apache.http.impl.nio.reactor.IOSessionImpl.getEventMask(IOSessionImpl.java:139)
        - locked <0x00000006cd91fef8> (a org.apache.http.impl.nio.reactor.IOSessionImpl)
        at org.apache.http.nio.reactor.ssl.SSLIOSession.updateEventMask(SSLIOSession.java:300)
        at org.apache.http.nio.reactor.ssl.SSLIOSession.inboundTransport(SSLIOSession.java:402)
        - locked <0x00000006cd471df8> (a org.apache.http.nio.reactor.ssl.SSLIOSession)
        at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:121)
        at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:160)
        at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:342)
        at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:320)
        at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:280)
        at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:106)
        at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:604)
        at java.lang.Thread.run(Thread.java:722)
Hope this helps!

Sunday, May 5, 2013

Load Balancing WSO2 ESB 4.6.0 using WSO2 ELB 2.0.3 - Pattern I - Distributed Setup with Separate Worker/Manager Nodes

I wrote a WSO2 Wiki article on explaining the minimum configuration instructions required to configure WSO2 ESB in a distributed setup with separated nodes as management node and worker node/s.

Shown below is the deployment diagram of this setup. The cluster consists of two sub cluster domains as worker/manager and is fronted by a single load balancer. Altogether, we will be configuring three service instances.


You can download esb-worker-mgt-deployment-pattern-1.zip file for the sample configurations discussed there, for ESB 4.6.0.

Monday, February 11, 2013

WSO2 Stratos-2.0.0 Beta-1 Released

WSO2 Stratos-2.0.0 Beta-1 is Released - 11th February 2013!

WSO2 Stratos2 team is pleased to announce the release of WSO2 Stratos 2.0.0 Beta-1 version.

WSO2 Stratos 2.0.0 Beta-1 is now available for download at [1] and the documentation is available at [2]. Stratos 2.0.0 Beta-1 installed, Oracle VirtualBox image, is downloadable at [3].
WSO2 Application Server Cartridge (LXC based), which is required at the run-time of the Stratos 2.0.0 Beta-1 VirtualBox image, is downloadable at [4].

WSO2 Stratos 2.0.0 is the next major version of WSO2 Stratos 1.x, the most complete, enterprise-grade, open PaaS, with support for more core services than any other available PaaS today.

Key Features
  • Artifact Distribution Coordinator (ADC) with Git and Git-hub integration support
  • Plug-able architecture support for adding new cartridges
  • PHP and MySQL and WSO2 carbon cartridges(ESB, AS etc) support
  • Elastic Load Balancer (ELB) with Cartridge support
  • Autoscaling into different IaaSes (EC2, Openstack)
  • S2 Cloud Controller
  • Multiple IaaS support (EC2, Openstack) through jclouds API's
  • Git based deployment synchronizer
  • Interactive CLI for tenants to manage subscriptions
  • UI for tenants to manage subscriptions
  • Custom domain mapping support
  • Script based Multi-node Installer
  • Local deployment setup
  • Examples
  • Documentation(Stratos2 Installation Guide, User Guide, Architecture Guide, Cartridge Development Guide and Openstack Installation Guide) 
  • Demo Ready Oracle VirtualBox image

You can report issues at [5] and [6].

Road to Stratos 2.0.0 Beta-1 (from Alpha)

Improvements

  • [SPI-16] - [Cloud Controller] Persist node details to registry
  • [SPI-41] - Cli list command results are not aligned properly.
  • [SPI-47] - ELB should pick the configuration via topology sync
  • [SPI-73] - Apply manager GUI improvements suggestions on feedback
  • [SPI-77] - Improve catching exceptions in ADC service side and Improve all cli error messages to inform the user about real error
  • [SPI-81] - Keep the maximum value of instances per cluster in back end configuration for Beta
  • [SPI-100] - Subscribe fails on concurrent requests

Bug Fixes

  • [SPI-17] - 'Alias' is already taken message isn't propagated and shown by the CLI client
  • [SPI-24] - When scaling down, instances are terminated below minimum number of instances
  • [SPI-25] - unsubscribe operation, when autoscaling option is enabled, doesnt remove the member from ELB
  • [SPI-26] - When Cloud controller is restarted topology info gets reset
  • [SPI-28] - Can't access lb url after subscribed by provided url
  • [SPI-30] - Missing Keypair Name in User Guide
  • [SPI-31] - CLI client should give a more appropriate error when user doesn't add required environment variables
  • [SPI-35] - Management Console in Manager node is not functioning properly
  • [SPI-36] - "virtual host only interface" its define as "vboxnet4"
  • [SPI-37] - INFO logs need to be replaced by DEBUG logs
  • [SPI-39] - Command line tool show wrong help when an action with mandatory arguments is called without the mandotory arguments
  • [SPI-40] - After subscribing to a cartridge GUI it goes to an error page
  • [SPI-42] - Domain mapping entry in Registry is not removed when the tenant unsubscribed to that cartridge.
  • [SPI-44] - Topology Builder thread spinning issue
  • [SPI-45] - Error in setup-demo script (w.r.t. keyPair property of a cartridge).
  • [SPI-46] - Incorrect log in hosting-mgt's repo notification service when there's only 1 active IP
  • [SPI-52] - Cloud controller path description given in setup-demo.sh is not correct
  • [SPI-61] - Info command should display repository url of the cartridge as well
  • [SPI-62] - List is not showing correct instance details in latest EC2 image
  • [SPI-66] - Include jars required to agent in default
  • [SPI-67] - Cartridge list command doesn't contain "host name" and "repo url" variables. They are null.
  • [SPI-78] - Changes to be done in carbon image setup file
  • [SPI-79] - When a non-super tenant is logged-in with validation for cli tool, back-end log is wrong. It say tenant domain carbon.super
  • [SPI-88] - "listCartridgeInfo" operation of ApplicationManagementService should throw an exception when the alias provided is not a registered one.
  • [SPI-89] - [Minor] Space is missing in an info log - authenticateValidation operation of ApplicationManagementService
  • [SPI-92] - "addDomainMapping" operation of ApplicationManagementService should throw an exception when the mapped domain is an already taken one.
  • [SPI-96] - Intermittent issue when connecting DB cartridge to php cartridge: Git repo creating error
  • [SPI-97] - Subscribing with a previously subscribed (and unsubscribed) alias wont spawn instances by ELB/ CC.
  • [SPI-108] - Application Server cartridge support in S2

Tasks

  • [SPI-48] - Remove the deprecated cartridge definition as.xml from the demo setup
  • [SPI-49] - Enable autoscaling by default in the EC2 image
  • [SPI-50] - Add mb_server_url entry to loadbalancer.conf of ELB in the set up
  • [SPI-63] - Test autoscaling in an EC2 environment
  • [SPI-70] - Committing the Git Based Depsync Message to Carbon Core
  • [SPI-86] - Make unncessary INFO logs of ApplicationManagementService to DEBUG

[5] Issue Tracker: https://wso2.org/jira/browse/SPI
[6] Openstack IaaS Issue Tracker : https://wso2.org/jira/browse/OZONE


-- WSO2 Stratos2 Team --

Friday, January 18, 2013

Scale up early... scale down slowly...





In a distributed system, ability to expand or contract its resource pool is defined as scalability. A system can be scaled in two modes, horizontal and vertical. What we are interested in is horizontal scaling which is adding more nodes to a clustered distributed system.

In this article, you will learn the auto-scaling algorithm used in WSO2 Elastic Load Balancer, few tips you should keep in mind when calibrating auto-scaling decision making variables and also a brief explanation on a sample scenario.

What is auto-scaling?


When there is a sudden peak of requests coming to an application, we should ideally increase the amount of resources we have provided for that application. There comes a solution call auto-scaling. In an auto-scaling enabled system, system itself should detect such peaks and start-up new server instances, to cater the requirements, without any manual interception.

With the revolutionization of Cloud, today we can easily start new instances and terminate already existing instances at any given moment, that makes auto-scaling a possibility in a Cloud environment.

Where does this autoscale decision making task reside?

The ‘autoscaling decision making’ task currently resides in WSO2 Elastic Load Balancer. Default implementation is “org.wso2.carbon.mediator.autoscale.lbautoscale.task.ServiceRequestsInFlightAutoscaler. 

What is the basis for autoscaling?

Current default implementation (ServiceRequestsInFlightAutoscaler) considers number of requests in-flight as the basis for making autoscaling decisions. We follow the paradigm; “scale up early and scale down slowly” in the default algorithm.

What are the decision making variables?

There are few of them and all of the vital ones are configurable using loadbalancer.conf file. (sample configuration files are provided at the end of this document.)
  1. autoscaler_task_interval (t) - time period between two iterations of ‘autoscaling decision making’ task. When configuring this value, you are advised to consider the time ‘that a service instance takes to join ELB’. This is in milliseconds and the default value is 30000ms.
  1. max_requests_per_second (Rps) - number of requests, a service instance can withstand per a second. It is recommended that you calibrate this value for each service instance and may also for different scenarios. Ideal way to estimate this value could be by load testing a similar service instance. Default value is 100.
  1. rounds_to_average (r) - an autoscaling decision will be made only after this much of iterations of ‘autoscaling decision making’ task. Default value is 10.
  1. alarming_upper_rate (AUR)- without waiting till the service instance reach its maximum request capacity (alarming_upper_rate = 1), we scale the system up when it reaches the request capacity, corresponds to alarming_upper_rate. This value should be 0
  1. alarming_lower_rate (ALR) - lower bound of the alarming rate, which gives us a hint; that we can think of scaling down the system. This value should be 0
  1. scale_down_factor (SDF) - this factor is needed in order to make the scaling down process slow. We need to scale down slowly to reduce scaling down due to a false-positive event. This value should be 0

How does the number of requests in-flight gets calculated?

We keep track of the requests that come to Elastic Load Balancer (ELB) for various service clusters. For each incoming request, we add a token, against the relevant service cluster and when the message left ELB or got expired, we remove the corresponding token.

What are the decision making functions?

We always respect the minimum number of instances value and maximum number of instances value of service clusters. We make sure that the system always maintains the minimum number of service instance requirement and also system will not scale beyond its limit.
We calculate,
average requests in-flight for a particular service cluster (avg) =
total number of requests in-flight * (1/r)

Scaling up....

number of maximum requests that a service instance can withstand over an autoscaler task interval (maxRpt) =
(Rps) * (t/1000) * (AUR)
then, we decide to scale up, if,
avg > maxRpt * (number of running instances of this service cluster)

Scaling down....

imaginary lower bound value (minRpt) =
(Rps) * (t/1000) * (ALR) * (SDF)
then, we decide to scale down, if,
avg < minRpt * (number of running instances of this service cluster - 1)

Can I plug my own implementation?

You can write your own Java implementation which implements org.apache.synapse.task.Task and org.apache.synapse.ManagedLifecycle interfaces. Wrap the implementation class to an OSGi bundle and deploy in WSO2 ELB. Then, point to that class from the {ELB_HOME}/repository/conf/loadbalancer.conf file’s loadbalancer section as follows.
loadbalancer {
…....
# autoscaling decision making task
autoscaler_task  org.wso2.carbon.mediator.autoscale.lbautoscale.task.ServiceRequestsInFlightAutoscaler;
…...
}

Sample configuration files

Properties defined in the defaults section.

loadbalancer {
        # minimum number of load balancer instances
        instances               1;
        # whether autoscaling should be enabled or not.
        enable_autoscaler   true;
        #please use this whenever url-mapping is used through LB.
        #size_of_cache                  100;
        # autoscaling decision making task
        autoscaler_task org.wso2.carbon.mediator.autoscale.lbautoscale.task.ServiceRequestsInFlightAutoscaler;
        # End point reference of the Autoscaler Service
        autoscaler_service_epr ;
        # interval between two task executions in milliseconds
        autoscaler_task_interval 30000;
        # after an instance booted up, task will wait maximum till this much of time and let the server started up
        server_startup_delay 60000; #default will be 60000ms
        # session time out
        session_timeout 90000;
        # enable fail over
        fail_over true;
}
# services' details which are fronted by this WSO2 Elastic Load Balancer
services {
        # default parameter values to be used in all services
        defaults {
            # minimum number of service instances required. WSO2 ELB will make sure that this much of instances
            # are maintained in the system all the time, of course only when autoscaling is enabled.
            min_app_instances           1;
            # maximum number of service instances that will be load balanced by this ELB.
            max_app_instances           3;
            max_requests_per_second   5;
            rounds_to_average           2;
            alarming_upper_rate 0.7;
            alarming_lower_rate 0.2;
            scale_down_factor 0.25;
            message_expiry_time         60000;
        }
        appserver {
            hosts          appserver.cloud-test.wso2.com;
            domains   {
                3.appserver.domain {
                    tenant_range        *;
                    min_app_instances           0;
                }
            }
        }
}

Properties defined within the service element

loadbalancer {
        # minimum number of load balancer instances
        instances               1;
        # whether autoscaling should be enabled or not.
        enable_autoscaler   true;
        #please use this whenever url-mapping is used through LB.
        #size_of_cache                  100;
        # autoscaling decision making task
        autoscaler_task org.wso2.carbon.mediator.autoscale.lbautoscale.task.ServiceRequestsInFlightAutoscaler;
        # End point reference of the Autoscaler Service
        autoscaler_service_epr ;
        # interval between two task executions in milliseconds
        autoscaler_task_interval 30000;
        # after an instance booted up, task will wait maximum till this much of time and let the server started up
        server_startup_delay 60000; #default will be 60000ms
        # session time out
        session_timeout 90000;
        # enable fail over
        fail_over true;
}
# services' details which are fronted by this WSO2 Elastic Load Balancer
services {
        # default parameter values to be used in all services
        defaults {
            # minimum number of service instances required. WSO2 ELB will make sure that this much of instances
            # are maintained in the system all the time, of course only when autoscaling is enabled.
            min_app_instances           1;
            # maximum number of service instances that will be load balanced by this ELB.
            max_app_instances           3;
            max_requests_per_second   5;
            rounds_to_average           2;
            alarming_upper_rate 0.7;
            alarming_lower_rate 0.2;
            scale_down_factor 0.25;
            message_expiry_time         60000;
        }
        appserver {
            hosts          appserver.cloud-test.wso2.com;
            domains   {
                3.appserver.domain {
                    tenant_range        *;
                    min_app_instances           0;
                        max_requests_per_second   5;
                        alarming_upper_rate 0.6;
                            alarming_lower_rate 0.1;
                }
            }
        }
}

Monday, December 24, 2012

WSO2 Stratos-2.0 - Cloud Controller - Part 1

What is Cloud Controller?

Cloud Controller plays a vital role in Stratos 2.0 and here I list its capabilities and duties.

WSO2 Cloud Controller,

  • is acting as a bridge between application level and Infrastructure as a Service (IaaS) level via Jclouds API.
  • enables your system to scale across multiple IaaS providers.
  • is the central location where the service topology resides.
  • is responsible for sharing the up-to-date service topology among other Stratos 2.0 core services, periodically.
  • supports hot update and deployment of its configuration files.
  • has inbuilt support for AWS EC2 IaaS provider and Openstack Nova IaaS provider.
  • enables you to cloud burst your system across multiple IaaS providers.
  • allows you to plug an implementation of any IaaS provider supports by jclouds, very easily.
  • enables you to spawn new service instances, while associating a public IP automatically, in order to reduce the instance boot-up time.
  • enables you to terminate an already started instance of a particular service cluster.
  • can be configured to cover many scenarios, using its well-thought-out configuration files.

Awaits the next post on Cloud Controller's SOAP Service Interface...

WSO2 Stratos-2.0 - Alpha released!

One rarely get a chance to release a product he is working on, on his Birthday. I'm lucky enough (Usually luck doesn't favour me :-(), to get such a chance.

WSO2 Stratos2 alpha was released on 19th December 2012, ya, that is my birthday.

I was mainly working on WSO2 Stratos-2.0 Cloud Controller, ELB etc. And I will elaborate on Cloud Controller in my future blog posts.

Tuesday, July 24, 2012

WSO2 Autoscaler Service - Part II



This is a continuation of my series of posts on WSO2 Autoscaler Service. If you missed the part-I, please visit here. As I mentioned there, in this post I will show how we secure the confidential information specified in the configuration file.

How to use WSO2 Secure Vault to secure your confidential data?


WSO2 Secure-vault can be used to hide your confidential data, from been appearing in the configuration files as plain text. In WSO2 Autoscaler service's configuration file i.e. elastic-scaler-config.xml file, we are securing the confidential information such as the identity and credential for accessing your account on an IaaS provider.

I will go through the steps you need to follow in order to secure an example property value.

In elastic-scaler-config.xml we have an element called “identity” at “elasticScalerConfig/iaasProviders/iaasProvider[@type='ec2']/identity”. Following is the exact element structure.
<identity svns:secretalias="elastic.scaler.ec2.identity"/>

Note that you don't need to provide your identity for a particular IaaS (EC2 in the case of the example) here, as plain text. Instead there is a secret alias defined as an attribute of the identity element, namely “ elastic.scaler.ec2.identity”.

Firstly, you need to add following line into the “${CARBON_HOME}/repository/conf/security/cipher-tool.properties”.
elastic.scaler.ec2.identity=elastic-scaler-config.xml//elasticScalerConfig/iaasProviders/
iaasProvider[@type='ec2']/identity,false

Structure of the above line is:
<secretAlias>=<nameOfTheConfigurationFile>//<XpathExpressionToThePropertyToBeSecured>,
<whetherTheXmlElementStartsWithACapitalLetter>

Then you need to edit the “${CARBON_HOME}/repository/conf/security/cipher-text.properties” file.
There you need to add your plain text confidential information against the secret alias.
elastic.scaler.ec2.identity=[abcd]
Structure of the above line is:
<secretAlias>=[<plainTextValue>]
Note that you need to add the plain text value within square brackets.

Now navigate to the “${CARBON_HOME}/bin” directory and run following command;

./ciphertool.sh -Dconfigure
Type primary key store password of Carbon Server, when prompted. The default value is “wso2carbon”.

Ok, that is it. Now if you revisit “${CARBON_HOME}/repository/conf/security/cipher-text.properties” file, you could see all your plain text data are replaced by cipher text.