CentOS 7.4에서 gitlab 제거

2019/06/14 15:47
설치되어 있는 gitlab을 제거하기 위해서는 다음과 같은 순서로 실행한다.
gitlab-ctl cleanse
gitlab-ctl uninstall
yum remove gitlab-ce

CentOS 7.4에 gitlab 설치하기

2019/06/13 13:28
Gitlab을 설치할 서버 OS 버전 : CentOS Linux release 7.4.1708 (Core)
설치할 Gitlab Version 및 Intallation Guide : https://about.gitlab.com/install/#centos-7

1. 사전 확인 작업 (안해도 됨)
Swap 파티션을 추가하고, swappiness를 설정한다.
sudo dd if=/dev/zero of=/swapfile count=4096 bs=1M
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile   none    swap    sw    0   0' | sudo tee -a /etc/fstab
free -m
시스템 성능을 위해서 kernel swappiness 설정은 10이하로 유지하는 것이 좋다.
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
cat /proc/sys/vm/swappiness
필요할 경우, 도메인을 설정한다.


2. 방화벽 설정
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo systemctl reload firewalld

만약, 설치 도중 [bash: firewall-cmd: command not found]과 같은 메시지가 뜬다면,
다음과 같이 firewalld를 설치해 주어야 한다.
sudo yum install -y firewalld

설치 완료 후, firewalld를 시작한다.
sudo systemctl unmask firewalld
sudo systemctl enable firewalld
sudo systemctl start firewalld

HTTP에 대한 방화벽 작업을 다시 설정한다.
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo systemctl reload firewalld

3. Notification Email을 위해서 postfix를 설치한다.
sudo yum install postfix
sudo systemctl enable postfix
sudo systemctl start postfix
만약, 외부 메일을 사용한다면 postfix 설치는 Skip하고 외부 SMTP 메일 서버를 설정한다.
아래는 gmail 설정 예제이다.
vi /etc/gitlab/gitlab.rb

gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.gmail.com"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "my.email@gmail.com"
gitlab_rails['smtp_password'] = "my-gmail-password"
gitlab_rails['smtp_domain'] = "smtp.gmail.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = false
gitlab_rails['smtp_openssl_verify_mode'] = 'peer'
# Can be: 'none', 'peer', 'client_once', 'fail_if_no_peer_cert', see http://api.rubyonrails.org/classes/ActionMailer/Base.html

자세한 정보는 https://docs.gitlab.com/omnibus/settings/smtp.html 에서 확인 가능

4. Repository에서 gitlab package 설치
<Enterprise Version>
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.rpm.sh | sudo bash
yum install gitlab-ce

<Community Version>
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
yum install gitlab-ce

5. cur : (60) Peer's Certificate issuer is not recognized. 오류 발생 시
rpm을 직접 다운로드 받아서 설치한다.
<rpm 다운로드>
wget --no-check-certificate --content-disposition https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/7/gitlab-ce-11.11.3-ce.0.el7.x86_64.rpm/download.rpm
<rpm 설치>
rpm -i download.rpm

6. gitlab 설정 변경 및 방화벽 오픈
<gitlab 설정 변경>
vi /etc/gitlab/gitlab.rb
external_url 'http://localhost' --> external_url 'http://{server ip}'
gitlab은 기본적으로 80포트를 사용하고, 내부 인증으로는 8080을 사용한다.
따라서 80포트에 대한 방화벽 오픈이 필요하다.
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --reload
7. gitlab 설정 변경 적용
마지막으로 변경된 gitlab 설정을 적용한다.
gitlab-ctl reconfigure
8. 최초 로그인
설치가 성공하면, 해당 서버의 IP를 치고 들어갔을 경우 비밀번호를 변경하게 된다.
관리자 계정의 비밀번호에 해당하므로, 비밀번호 변경 후 [root / 변경비밀번호]로 로그인한다.


9. 참조 Sites.







Continuous Integration Environment Reference Model

2019/04/25 14:58
기본적인 Continuous Integration 환경에 대한 다이어그램
사용자 삽입 이미지

Windows에서 OpenJDK 사용

2019/03/13 13:39
오라클에서 Sun을 인수한 이후, JDK 유료화 정책으로 인해 Java 프로그래밍을 하는 세상에 지각 변동이 일어났습니다.

리눅스에서는 이전부터 OpenJDK를 사용하였는데, Windows에서도 사용할 수 있도록 오픈되었네요.

https://github.com/ojdkbuild/ojdkbuild

앞으로는 OpenJDK를 사용해야 할 듯...

Java Singleton Class

2019/03/11 21:45
일반적으로, 메모리에 하나의 Instance만 로딩되도록 해야 하는 경우 Singleton Pattern을 적용한 Singleton Class를 사용한다.

하지만, 대용량의 트래픽이 발생하는 Concurrent Request 환경에서는 하나의 Request가 곧 하나의 Thread를 실행하게 된다. 그런 경우, Singleton Class는 Thread-Safe하지 않게 될 수 있다.

원치 않게 각 요청에 따른 올바른 Response를 주지 못하고, 데이터가 꼬여 다른 결과를 리턴하게 되는 치명적인 결과가 초래될 수 있다.

모든 경우와 같이, Singleton Class를 제공하는 경우에도 다음과 같은 고려가 필요하다.

- 동시에 여러 개의 요청이 오더라도 순서대로 처리할 수 있어야 한다.
- 최대한의 성능을 고려해야 한다.
- 여러 요청으로 인해 병목이 발생하더라도 다른 작업을 처리하고 있는 Thread에 영향을 최소화해야 하고, 프로그램이 종료되지 않아야 한다.

Singleton Class 구현 방법은 다음과 같은 방법으로 생각해 볼 수 있다.

<1> Eager Initialization
package com.dev.sample

public class EagerInitSingleton {

private static final EagerInitSingleton = new EagerInitSingleton();
private EagerInitSingleton () {}

public static EagerInitSingleton getInstance() {
return instance;
}
}
Class Loading 시점에 Singleton Class Instance가 생성된다. 가장 쉽게 Signleton Class를 생성하는 방법이지만, Client에서 요청이 없을 때에도 항상 생성되므로 불필요한 리소스를 사용하게 된다. 또한 대부분 파일 시스템이나 데이터베이스에 접속하는 경우 Singleton Class를 사용하는데 Exception을 처리할 수 없다.

<2> Static Block Initialization
package com.dev.sample

public class StaticBlockSingleton {

private static StaticBlockSingleton instance;

private StaticBlockSingleton () {}

static {
try {
instance = new StaticBlockSingleton();
}
catch (Exception e) {
throw new RuntimeException(e.printStackTrace());
}
}

public static StaticBlockSingleton getInstance() {
return instance;
}
}
Static Block은 Eager Initialization Singleton과 비슷하게 Class Loading 시점에 Static Block 안에서 Singleton 객체가 생성되지만, Exception을 처리할 수 있다. 하지만, 동일한 단점을 가지고 있다.

<3> Lazy Initialization
package com.dev.sample

public class LazyInitSingleton {

private static LazyInitSingleton instance;

private LazyInitSingleton() {}

public static LazyInitSingleton getInstance() {

if (instance == null) {
instance = new LazyInitSingleton();
}

return instance;
}
}
Single Thread 환경에서 잘 동작한다. 하지만, 동시에 여러 개의 Thread가 접근할 경우 여러 개의 Instance가 생성될 수 있다. 그런 경우 Singleton Pattern이 깨지고, 서로 다른 Singleton Instance를 사용하게 될 수 있다.

<4> Thread-Safe Singleton
package com.dev.sample

public class ThreadSafeSingleton {

private static ThreadSafeSingleton instance;

private ThreadSafeSingleton() {}

public static synchronized ThreadSafeSinfleton getInstance() {

if (instance == null) {
instance = new ThreadSafeSingleton();
}

return instance;
}
}
synchronized 키워드를 사용하여 한번에 하나의 Thread만 호출할 수 있도록 만들 수 있다. 하지만 모든 Thread의 요청에 대해 synchronized를 실행하므로 성능상 오버헤드가 발생한다.

<5> Double Checked Thread-Safe Singleton
package com.dev.sample

public class DoubleCheckThreadSafeSingleton {

private static DoubleCheckThreadSafeSingleton instance;

private DoubleCheckThreadSafeSingleton() {}

public static DoubleCheckThreadSafeSingleton getInstance() {

if(instance == null) {
synchronized (DoubleCheckThreadSafeSingleton.class) {
if (instance == null) {
instance = new DoubleCheckThreadSafeSingleton();
}
}
}

return instance;
}
}
위와 같은 Double Checked Locking 원리를 이용하면, 조건을 만족시키는 경우 (instance == null) 한 번만 synchronized block이 실행되므로 하나의 Singleton Class Instance만 생성된다. synchronized로 인한 성능 이슈를 해소할 수 있다.

<6> On-demand Holder Idiom에 따른 Inner Class(holder or helper class)를 이용한 Singleton
package com.dev.sample

public class HelperSingleton {

private HelperSingleton() {}

private static class SingletonHelper {
private static final HelperSingleton instance = new HelperSingleton();
}

public static HelperSingleton getInstance() {
return SingletonHelper.instance;
}
}
getInstance() method를 호출 할 때, SingletonHelper 클래스가 생성되고 Singleton intance는 static final 키워드로 인해 한번만 생성된다. 대부분 <6>번의 경우를 많이 사용한다.