AWS – EC2 – Ubuntu – XRDP 환경 구성

집에서 서버를 구축해서 사용을 해보면 SK, KT 등 통신사를 통하기 때문에
고정 IP 를 사용할 수 없다던지, Proxy 서버에 차단된다던지 하는 어려움도
존재하고 전기비도 생각하는 것보다 엄청 많이 나오는 관계로 AWS사용을
적극 검토하게 되었다. 오늘 작성하려는 내용은 AWS 에 EC2 서비스를 사용
Ubuntu 를 설치하고 Terminal 접속만 되는 문제를 해결하고자 XRDP 를
설치하여 접속하는 것 까지 작성하겠다.
RedHat 은 http://devopscube.com/how-to-setup-gui-for-amazon-ec2-rhel-7-instance/

1. Google 에서 AWS 를 검색하여 아래 페이지에 접속 후 계정을 생성하여
로그인 한다.

K-093

2. 아래와 같이 서비스 목록이 나오는데 우상단에 서비스 지역을 Seoul로 꼭 바꾸고
EC2 서비스를 실행한다.
K-096

3. Launch Instance Click

K-097

 

4.  자신이 원하는 Platform 을 선택하면 된다. 여기서는 Ubuntu 선택
K-098

 

5. CPU 수와 RAM 등을 지정한다. (t2.micro 는 1년간 무료이다 )

K-100

6.  Network 설정 Default 로 가자
K-101

7. HDD 용량이다 최대 30G 까지 설정 가능
K-102

8. 이하 Defulat로 설정 – Review and Launch
K-105

9. Key 생성 (꼭해야 함. 아무 이름이나 원하는 것 입력)

K-107
10. Instnace 가 생성된 것을 볼 수 있다.
K-108

11. 접속을 위해서 PUTTY 와 PUTTYGEN 을 다운로드 받는다.
K-112

12. Puttygen 을 실행하여 (10)에서 생성한 pem 파일을 ppk 로 변환
– LOAD -> PEM 선택 -> save private key -> 동일 이름으로 저장
K-113

※ 고정IP를 사용하고 싶을때는
VPC > Elastic IPs > Allocate New Address > Action > Associate Address > Instance 선택 을 해주면 해당 Instacne 는 항상 Elastic IPs 로 접속된다.
Elastic IPs 의 경우 연결된 Instacne 없이 방치 되면 요금이 부과된다.

13. putty 를 이용해서 instacne 에 접속한다.
– Instance 이름을 ubuntu 로 입력한다.
– Connection 주소는 instance 명 @ public DNS 이다

K-117 K-120

14. 아까 만든 pem 파일을 SSH -> Auth 에서 Load 한다
K-120

15. (14)까지 완료 후 접속하면 아래와 같이 접속이 된다.

K-121

 

16. 이제 XRDP 를 통해 윈도우에서 원격 접속할 수 있는 환경을 만들어 보자
K-126

 

17. 아래 명령어를 통해 apt-get 을 업그레이드 한다
sudo apt-get update
sudo apt-get upgrade

18. 아래 파일을 편집한다
sudo vim /etc/ssh/sshd_config
PasswordAuthentication  내용을 yes 로 변경

19. 변경 파일 즉시 적용
sudo /etc/init.d/ssh restart

20. 아까 만들었던 ubuntu 계정의 비밀번호 설정
sudo –i //superuser 권한 임시 획득
passwd ubuntu

21. ubuntu 계정으로 다시 전환
su ubuntu
cd

22. ubuntu desktop 을 설치 합니다.
export DEBIAN_FRONTEND=noninteractive
sudo -E apt-get update
sudo -E apt-get install -y ubuntu-desktop

23. XRDP 와 xfce4  를 설치 합니다.
sudo apt-get install xfce4 xrdp
sudo apt-get install xfce4 xfce4-goodies

24. xfce4 가 기본 메니져가 되도록 설정합니다 .
echo xfce4-session > ~/.xsession

25. ubuntu user계정에 복사 합니다. (계정 추가시 동일 행위 필요)
sudo cp /home/ubuntu/.xsession /etc/skel

26. xrdp.ini 를 편집합니다.
sudo vim /etc/xrdp/xrdp.ini

27. xrdp.ini 파일내  xrdp1 그룹의 아래 내용을 수정합니다.
port=-1
– to –
port=ask-1

28. 서비스를 restart 합니다.

sudo service xrdp restart

29. RDP 연결의 기본 PORT 는 3389 이며, Rule 에서 별도로 허용 처리 필요
※ 포트를 변경하고자 할 경우
sudo vi /etc/xrdp/xrdp.ini
[globals]
port=3389    
//해당 값 변경
sudo service xrdp restart

※ 방화벽 OPEN
sudo firewall-cmd –permanent –add-port=3389/tcp
sudo firewall-cmd –reload

K-127

K-128

 

30. 원격접속을 시도해 봅니다.
K-129 K-130

K-131

 

여기까지 기본 환경은 구성하였으며, 이에 이 위에 Git 서버 , WordPress 등 유틸성격의 서비스를 설치하고  Spark , Hadoop, Eclipse, Tomcat, DeepLearning4Java 등을 설치하여 실제 서비스를 올리는 부분은 정리가 되면 업데이트 하겠습니다.

JAVA – Thread Safe Programming

  1. Automic (원자성)

    – 원자성이란 CPU 가 처리하는 하나의 단일 연산
    예를들어 int a = 1 , int a = 1+1 은 원자성 연산이지만, a++ 은 원자성 연산이 아니고,
    [a 의 값을 읽는다] 와 [a의 값을 증가 시킨다] 두 가지 원자 연산의 조합이다.

public class AtomicTest {
 private int a=0;
 public int incrementAndGet(){
  return a++;
 }
 public static void main(String[] args) {
  final AtomicTest test = new AtomicTest();
  for (int i = 0; i < 100; i++) {
   new Thread(){
    public void run(){
     for (int j = 0; j < 1000; j++) {
      System.out.println(test.incrementAndGet());
     }
    }
   }.start();
  }
 }
}

 

위의 코드를 보면 100 개의 Tread 를 생성해서 각 Tread 가 1000개의 값을 증가 시키도록 하는 코드인데, 실제로 실행해보면 100 X 1000 이 아닌 그보다 적은 값이 결과로 출력된다. 그 이유는 아래와 같이 설명될 수 있다.
A Thread : i = 0 Load
B Thread : i = 0 Load (A가 + 하기 전)
A Thread : i = i + 1 저장
B Thread : i = i + 1 저장
결론적으로 두번의 +1 이 이루어 졌으나, 결과 값을 1인 상황이 발생

2. Thread Safety 발생 CASE 예

(1) 명시적으로 Thread 사용시

public class ThreadSafety {

    public static void main(String[] args) throws InterruptedException {
    
        ProcessingThread pt = new ProcessingThread();
        Thread t1 = new Thread(pt, "t1);
        t1.start();
        Thread t2 = new Thread(pt, "t2");
        t2.start();
        //wait for threads to finish processing
        t1.join();
        t2.join();
    }
}

class ProcessingThread implements Runnable{
    private int count;
    
    @Override
    public void run() {
        for(int i=1; i < 5; i++){
            processSomething(i);
         count++;
        }
    }
}

 

(2) static 변수를 Member 변수로 사용하는 경우

class MyCounter {
  private static int counter = 0;
 
  public static int getCount() {
    return counter++;
  }
}

 

(3) Webservice 를 생성하는 경우
– 아래 예는 WebLogic Webservice

@WebService(name=MyCounter)

class MyCounter {
  private int counter = 0;

 

@WebMethod

 
  public int getCount() {
               return counter++;
  }
}

 

(4) Servlet
– 아래 예는 Spring F/W

@Servicepublicclass

 MyCounter 

{    @Autowired    private int counter = 0;

    public int getCount() {
               return counter++;
    }

}

 

(5) REST 는?
– REST (JAX-RS 기반) 의 경우 Thread Safe 하다고 한다
– 모든 Request 마다 새롭게 자원 할당

3. Thread Safe Programming

(1) Automic Class 사용
– 아래와 같이 Automic Class 를 사용하면 두 Cycle 로 나누어진 작업을 하나로
수행할 수 있게 되며, 이에 따라 위에 설명한 Thread 문제 회피 가능

@WebService(name=MyCounter)

class MyCounter {
  AtomicInteger counter= new AtomicInteger( 0 );

 

@WebMethod

 
  public int getCount() {
               return counter

.incrementAndGet();

  }
}

 


 (2) Vector , HashTable, CuncurrentHashMap, String 사용
– 위의 Class 들은 Thread Safe 하다. 비슷한객체인 HashMap 은 Thread Safe
하지 않다. Thread Safe 가 필요한 경우 위의 변수를 활용한다.

ArrayList<String>crunchifyArrayList=newArrayList<String>(); List<String>synchronizedList=Collections.synchronizedList(crunchifyArrayList); Map<String, String> crunchifyMap = new HashMap<String, String>(); Map<String, String> synchronizedMap = Collections.synchronizedMap(crunchifyMap);

 

 

(3) Local 변수 사용
– Local 변수는 Thread Safe하다.이유 없이 Member변수 사용하지않도록 한다

(4) Synchronized 사용
– Lock & UnLock 을 통해 한시점에 하나의 Thread 만 해당 Method 혹은 Block 을 실행할 수 있도록 Thread 를 제어한다. 사용 방법은 아래와 같이 간단하지만 잘 못 사용시 시스템 성능 저하를 가지고 올 수도 있다.

//Method 동기화
class MyCounter {
  private static int counter = 0;
 
  public static 

synchronized

 int getCount() {
    return counter++;
  }
}

//Block 동기화
private Object obj = new Object();
class MyCounter {
  private static int counter = 0;

  public static 

synchronized

 int getCount() {
   synchronized(obj) {
      return counter++;
   }
  }
}

 

(5) Double Check Locking
– 위의 Synchronized 는 Thread Safety 는 확실하게 하지만 성능 저하라는 큰 문제가 존재함 이를 해결하기 위해 DCL 같은 방법이 사용

public class Singleton {    private volatile static Singleton uniqueInstance;    private Singleton() {   }    public static Singleton getInstance() {        if (uniqueInstance == null) {            // 이렇게 하면 처음에만 동기화 된다            synchronized (Singleton.class) {                if (uniqueInstance == null) {                    uniqueInstance = new Singleton();                }            }        }        return uniqueInstance;    }}

 


(6) ThreadLocal
– ThreadLocal 은 Scope 내에서만 공유되는 변수의 특성상 Scope 을 넘어서 전달하기 위해서는 파라메터 형태로 전달해야하는 불편함을 없에고 동일 Thread 내에서는 변수가 공유되는 특성을 갖는다. 또 이러한 특성을 이용하여 멀티 Thread 환경에서 다른 Thread 에서의 간섭을 배제하는 용도로도 사용가능

// 현재 쓰레드와 관련된 로컬 변수를 하나 생성한다.
ThreadLocal<UserInfo> local = new ThreadLocal<UserInfo>();

// 로컬 변수에 값 할당
local.set(currentUser);

// 이후 실행되는 코드는 쓰레드 로컬 변수 값을 사용
UserInfo userInfo = local.get();

 

(7) Volatile
– 하나의 Thread 에서는 읽기/쓰기 작업을 수행하고 다른 Thread 에서는 읽기 작업만 하는 경우  최신 정보를 읽을 수 있도록 보장해 줌 . 단, 양쪽이 모두 읽기/쓰기 작업이라면
Synchronized 등 다른 방법을 사용해야 함

public class SharedObject {

    public volatile int counter = 0;

}