Archive

Archive for the ‘Teknologi Informasi’ Category

Load Balancing With NGinX

May 7, 2018 Leave a comment

Why we need load balancer ? can we just create one very stable server which is the failure rate zero and when we need to implement this load balancer ?

Load balancing at least has two main purposes :

  1. Increasing fault tolerance
  2. Distributing load

Increasing fault tolerance means ensuring and increasing uptime and reliability current application or system. This is very critical for such services which sale high availability of their services which is once downtime happened exceeding the tolerance limit, will cause big trouble and endanger their business continuity. Nowadays, for example when services like Facebook, or whatsapp down, users which are rely on FB and Whatsapp as their backbone business, will lose trust and if this happened frequently will abandoned FB and Whatsapp and worst case will move to competitor services.

Second purposes of load balancing is distributing load. This load distribution make scaling (Horizontal Scale) will much more easier to do instead of increasing capacity and specification in one single server. This will have much more advantages for high levels concurrency transaction. Using load balancer, we can increase or remove server easily without downtime and of course will drive to cost savings in final result.

In this post we will use and configure NGinX as load balance using 3 major techniques :

  1. Round-Robin
  2. Least Connections
  3. Hash Load Balancer

 

ROUND ROBIN

This is could be the most common and simple mechanism in load balancer which the request will be processed by the first available server in defined stack, second request will be handled by the second server in stack and so on in rotational basis. This could be seen in loop pattern, which the handling process request will back to first server when last server has processed the request.

Round Robin load balancer has one advantages, that no need further configuration in server side, but also has disadvantages that will ignore current server load because no such check mechanism to ensure that current server can handle the request.

For example we have two identical rails apps which run each on port 3000 and 4000 in local server, and has each own id. Imagine this only small apps which only echo out the the app id. The nginx config will be like this :

Inside upstream block directive under http directive, we define two server and name of the server. Along with first server definition (127.0.0.1:3000), we also define weight to indicate the server capacity. it means, first server will serve request 3 times higher than other server. this will be useful if we have two different server with different capacity.  in server directive, we use proxy_pass directive to point all traffic to upstream directive.

NGinX will use round-robin algorithm by default because we didn’t specify any algorithm. this configuration will make all request served sequentially by upstream server. first request will handled by first server, second request by second server and so on.

LEAST CONNECTION

In Least Connection algorithm, request will distributed to server with lower active connection. This mechanism different with round-robin that does not consider any server load or response time when distributing request. Least Connection algorithm assumes connection proportional to server load.

This is sample of NGinx config using Least Connection Algorithm:

as we can see from config above, the main difference is we define algorithm least_conn in upstream directive.

this will make when request come in, NGinx will determine which server has lower active connections and will assign the request into this server.

HASH LOAD BALANCING

When a Load balancer is configured to use the hash method, it computes a hash value, commonly client’s IP address is used as pattern to match, then sends the request to the server, ensuring that connections within existing user sessions are consistently routed to the same back-end servers. This means every subsequent request from same hash will always route to same upstream server.

The config it self same as with RR and Least Connection algorithm. The difference is we define hash in upstream block, and use client remote address as the key factor to build the hash.

 

As conclusion, NGinX support these 3 Algorithm when we set NGinX as load balancer. From the simple one Round-robin algorithm to more complex hash algorithm.

For further reading can refer to NGinX documentation here.

 

Jakarta, May 7Th 2018

 

Aah Ahmad Kusumah

Advertisements

Grant Table User to Another User [Oracle]

August 22, 2016 Leave a comment

Below is snippet command for granting user table to another user

declare
  cursor t_name is select table_name from user_tables ;
  command varchar2(500);
begin
for c in t_name loop
command := 'GRANT SELECT, INSERT, UPDATE, DELETE ON ' ||c.table_name|| ' TO <other_user>';
   dbms_output.put_line(command);
   execute immediate command;
end loop;
end;


Jakarta, 24 August 2016

 

A. Ahmad Kusumah

Pointing Domain into AWS EC2

July 22, 2016 Leave a comment

Pointing domain into AWS EC2 is quite simple, what need todo are :

  1. Create EC2 instance, then write down the IP address (i.e 10.10.2.10)EC2 Management Console 2016-07-22 15-31-35
  2. Open Route 53 in AWS console (https://console.aws.amazon.com/route53/)
  3. Now you are in route 53, select DNS Management, or choose Hosted Zones in sidebar menu, then select Create Hosted ZoneRoute 53 Management Console 2016-07-22 15-35-40
  4. Type  your domain name, select type to Public Hosted Zone, then press Button CreateRoute 53 Management Console 2016-07-22 15-36-51
  5. Then Create Record Set, and create A record, and point address to your EC2 public IP in point 1Route 53 Management Console 2016-07-22 15-41-38
  6. Then write down NS from Created Hosted Zone, and change you domain name NS using NS from Hosted Zone. the changes will reflect immediatelly, but for some provider need to wait till 24 hours.Route 53 Management Console 2016-07-22 15-43-13
  7. And voila, now you have successfully point and associate your domain name into your AWS EC2 instance.

 

Jakarta, Friday 22 July 2016

 

A. Ahmad Kusumah

Running Multiple Java Version On OSX

September 6, 2015 Leave a comment

Currently i have several projects using different version java, the oldest one using java 1.6, and the new one using 1.8 which is need lambda expression supported by latest version of java.

and i have only one machine that running OSX yosemite, sometimes i need run java 1.6 and sometimes need java 1.8 as my default running java version.

Below is quick guide how to install multiple java and switch between them easily and fast.

  1. Install Java , from the oldest version to the latest one. 1.6, 1.7 then 1.8. Do not from the latest one or you will get problem when installing the old one.
  2. Check the default java, using command : java -version Screen Shot 2015-09-06 at 7.38.49 PM
  3. Create simple script as below :
    1. first create script to set JAVA_HOME variable with version using shell input
      • export JAVA_HOME=$(/usr/libexec/java_home -v $1)
    2. Second create Symbolic Link from JAVA_HOME to CurrentJDK [for elcapiten, no need this step]
      • sudo ln -nsf ${JAVA_HOME%/*} /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK
      • option s , for create symbolic, option f force symbolic link with unlink first if symbolic link already exist, option n , prevent symbolic link if source or target is symbolic link
    3. Put the script into /etc/profile, named for example usejava
      • usejava() { export JAVA_HOME=$(/usr/libexec/java_home -v $1)

        #For Elcapiten, please comment out this line below#

        sudo ln -nsf ${JAVA_HOME%/*} /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK}usejava 1.6

  4. For change default java, just use command :
    1. usejava 1.6 –> switch 1.6 as default version
    2. usejave 1.7 –> switch 1.7 as default version
    3. usejava 1.8 –> swicth 1.8 as default version

 

Bogor, September 6th 2015

 

A. Ahmad Kusumah

Password life time on oracle

July 17, 2012 1 comment

Alter Profile

By default, user created in oracle has password expiration on 180 days. It means, when the time reached, the user will be forced to change their current password. This mechanism from security view is has advantages, it makes user aware to always maintain their current profile and data.

But, in other hand, sometimes an application need user with no expiration date of password such as ERP, Procurement etc. In order to facilitate this needs, there’s 2 ways to do so :

  1. Create stand alone profile with unlimited expiration date and assign to user
  2. Update user current profile, set limit of password expiration to unlimited

This time we’ll show the second method, update user current profile.

The steps are :

1. check current user profile using command :

select profile from dba_users where username='<username>’;

2. Change limit of password expiration policy o unlimited

alter profile <profile_name> limit password_life_time UNLIMITED;

3. Check profile after to make sure policy has been updated

select resource_name,limit from dba_profiles where profile='<profile_name>’;

Now,all users with this profile has no expiration date policy for their password …

Lampung, 17 July 2012

Aah Ahmad Kusumah

(IT Professional Consultant and Developer)

Loading Purchase Request Using Mincom Connector Java .. (Ellipse Part 1)

July 12, 2012 1 comment

MSO 230

Integration between java and mincom ellipse v.5 is quite tricky. Although mincom provide middleware to facilitate the integration, but we should know all model used in ellipse screens.

Below is first part on how we can communicate and loading data from java application into ellipse server.

In this example will explain about Purchase Request creation.

1. Firstly we should innitiate connection to ellipse server, get connection and store the session.

this is the class to handle connection :

package com.ellipse.main;

import java.io.IOException;
import java.io.InterruptedIOException;

import com.mincom.mims.tech.mware.cbr.CBRException;
import com.mincom.mims.tech.mware.common.EllipseLoginException;
import com.mincom.mims.tech.mware.common.IMimsSession;
import com.mincom.mims.tech.mware.common.MimsSessionFactory;
import com.mincom.mims.tech.mware.common.MwareException;

public class ConnectionEllipse {

private IMimsSession mySession;
private String buflib = “DOWNLOADED_XML”;

String tp;
String host;
String port;
String userHost;
String passHost;

String userEllipse;
String passEllipse;
/**
* EllipseConnection constructor
*/
public ConnectionEllipse() {
initConnection();
}
private void initConnection(){
try{
this.tp = “Cics”;
this.host = “10.1.1.160:ellprd”;
this.port = “0”;
this.userHost = “guest”;
this.passHost = “guest”;
this.userEllipse = “USER”;
this.passEllipse = “USERPASS”;
}catch (Exception e) {
e.printStackTrace();
}
}

/**
* Set the location of the bfl files (for MSO access)
* @param location
*/
public void setBufferLibraryLocation(String location) {
buflib = location;
}

/**
* Connect to the Ellipse server
* @param TP
* @param hostName
* @param portNumber
* @param hostUsername
* @param hostPassword

* @throws EllipseLoginException
* @throws EllipseConnectionException */

public void connect(String TP, String hostName, int portNumber, String hostUsername, String hostPassword) throws EllipseLoginException {

MimsSessionFactory sessionFactory = MimsSessionFactory.getMimsSessionFactory();
mySession = sessionFactory.getMimsSession(TP,buflib);
//            mySession.setTracing();
try {
mySession.connect(hostName, portNumber, hostUsername, hostPassword);
} catch (InterruptedIOException e) {
throw new EllipseLoginException(e.toString());
} catch (IOException e) {
e.printStackTrace();
throw new EllipseLoginException(e.toString());
} catch (CBRException e) {
throw new EllipseLoginException(e.toString());
}
}

/**
* connect without injecting patameter

* @throws EllipseLoginException */
public void connect() throws EllipseLoginException {

MimsSessionFactory sessionFactory = MimsSessionFactory.getMimsSessionFactory();
mySession = sessionFactory.getMimsSession(this.tp,this.buflib);
//            mySession.setTracing();
try {
System.out.println(this.host+”>>> “+this.passHost);
mySession.connect(this.host,0, this.userHost, this.passHost);
} catch (InterruptedIOException e) {
throw new EllipseLoginException(e.toString());
} catch (IOException e) {
e.printStackTrace();
throw new EllipseLoginException(e.toString());
} catch (CBRException e) {
throw new EllipseLoginException(e.toString());
}
}

/**
* This method attempts to login to the Ellipse server.
* @param mimsUser
* @param mimsPwd
* @param district
* @param position

* @throws EllipseLoginException
* @throws EllipseConnectionException */
//login to mims
public void login(String mimsUser,String mimsPwd,String district,String position) throws EllipseLoginException {
try {
mySession.login(mimsUser,mimsPwd,district,position);
} catch (CBRException e) {
throw new EllipseLoginException(trimQuotes(e.toString()));
} catch (MwareException e) {
throw new EllipseLoginException(trimQuotes(e.toString()));
} catch (com.mincom.mims.tech.mware.common.ServerException e) {
throw new EllipseLoginException(trimQuotes(e.getLocalizedMessage()));
} catch (IOException e) {
throw new EllipseLoginException(trimQuotes(e.toString()));
}
}

/**
* using param from ellipse.properties

* @throws EllipseLoginException */
public void login() throws EllipseLoginException {
try {
mySession.login(this.userEllipse,this.passEllipse,”PTBA”,””);
} catch (CBRException e) {
throw new EllipseLoginException(trimQuotes(e.toString()));
} catch (MwareException e) {
throw new EllipseLoginException(trimQuotes(e.toString()));
} catch (com.mincom.mims.tech.mware.common.ServerException e) {
throw new EllipseLoginException(trimQuotes(e.getLocalizedMessage()));
} catch (IOException e) {
throw new EllipseLoginException(trimQuotes(e.toString()));
}
}

/**
* This method attempts to disconnect from the Ellipse server.

* @throws EllipseLoginException
* @throws EllipseConnectionException */
//disconnect from mims server
public void disconnect() throws EllipseLoginException {
try {
mySession.disconnect();
} catch (IOException e) {
throw new EllipseLoginException(e.toString());
} catch (CBRException e) {
throw new EllipseLoginException(e.toString());
}
}

/**
* Get the current connection to Ellipse

* @return IMimsSession: The current Ellipse session */
public IMimsSession getSession() {
return mySession;
}

/**
* Trim the error message and remove double quotes
* from the ends of the message.
* @param errorMessage String
* @return String
*/
private String trimQuotes(String errorMessage) {
// Start with initial trim
String trimMessage = errorMessage.trim();
// Strip double quotes (“) from error message
if (trimMessage.startsWith(“\””) && trimMessage.endsWith(“\””)) {
trimMessage = trimMessage.substring(1, trimMessage.length()-1);
}
// Trim again on the way out
return trimMessage.trim();
}
}

2. Second step is identify all field screen model on Purchase Request ( MSO 230)

/**
* creating PR
* @param session
*/
public void createPr230(IMimsSession session){
try {
ScreenObject mso = session.executeMSO(“MSO230”);
/** Multi Item PR**/
mso.getFields().item(“OPTION1I”).setValue(“2”);
mso = mso.getCommands().item(“OK”).execute();

/** input requester **/
mso.getFields().item(“REQUEST_BY1I”).setValue(“28025”);
mso.getFields().item(“REQ_BY_DATE1I”).setValue(“18092012”);
mso.getFields().item(“PRIORITY_CODE1I”).setValue(“NORM”);
mso = mso.getCommands().item(“OK”).execute();

/** input item **/
mso.getFields().item(“TYPE1I1”).setValue(“G”);
mso.getFields().item(“QTY_REQD1I1”).setValue(“10”);//quantity
mso.getFields().item(“ACT_GROSS_PR1I1”).setValue(“1000000”);//price
mso.getFields().item(“UOM1I1”).setValue(“AMP”);//UOM
mso.getFields().item(“PART_NO1I1”).setValue(“”);
mso.getFields().item(“ACTION1I1”).setValue(“A”);//input cost center

/** item description **/
mso.getFields().item(“DESC_LINE_11I1”).setValue(“BLA”);
mso.getFields().item(“DESC_LINE_21I1”).setValue(“BLA”);
mso.getFields().item(“DESC_LINE_31I1”).setValue(“BLA”);
mso.getFields().item(“DESC_LINE_41I1”).setValue(“BLA”);
mso = mso.getCommands().item(“OK”).execute();

/** insert cost center **/
mso.getFields().item(“COST_CEN_ACCT1I1”).setValue(“234509876”);
mso = mso.getCommands().item(“OK”).execute();

/** final execution **/
mso = mso.getCommands().item(“OK”).execute();

} catch (Exception e) {
e.printStackTrace();
}
}

 

Voila, now our Purchase Request Has been created …

Continued to 2nd Part ….

 

Lampung, Juli 12 2012

Thursday

 

 

A. Ahmad Kusumah

(Professional IT Consultant)

Clean Up Oracle archive log using cron

July 1, 2012 Leave a comment

Cron List

Oracle has capability for creating hot backup using archive log mechanism. This feature act like recovery data system for restoring database content to specified time if the original database has force majeur which make data corrupted.

But, this mechanism will suck up the free space of hard disk and typically if we don’t maintain the following problem maybe occured :

1. The Space allocated for archive run out which make all transaction will be suspended

2. Hard disk space will be run out

Usually we can delete completed archive log using RMAN command, but this sometimes takes time.

Below is automation script for deleting completed archive log using cron.

1. create script (named cleanarchive.sh)

#!/bin/bash
export ORACLE_BASE=/database/oracle/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/dbhome_1
export ORACLE_OWNR=oracle
export ORACLE_SID=orcl
export PATH=$PATH:$ORACLE_HOME/bin

su – oracle -c rman target / << __EOF__
DELETE NOPROMPT ARCHIVELOG ALL COMPLETED BEFORE ‘SYSDATE -7’;
EXIT
__EOF__

2. create new job on cron sequence (will be executed everyday at 22:55)

crontab -e

55 22 * * * /bin/sh /database/oracle/crontab/cleanarchive.sh >/database/oracle/crontab/arch.log 2>&1

3. Restart cron service

Voila …, now the completed archive log will be checked and cleaned up every day, and we just left the archive less then 7 day till the day executed.

 

Tanjung Karang, Lampung

July, 1st 2012

 

Aah Ahmad Kusumah