네이버 클라우드 활용해서 3tier 구축
나를 살려준 블로그 목록
https://passwd.tistory.com/entry/Apache-Tomcat-WAR-%EB%B0%B0%ED%8F%AC
[Apache Tomcat] WAR 배포
개요 2022.08.23 - [Ubuntu] Apache Tomcat 설치에서 설치한 Tomcat에 WAR로 패키징된 애플리케이션을 배포하려고 한다. 배포할 애플리케이션은 이미 maven 등으로 빌드해두었다고 가정한다. 이 글에서는 https:
passwd.tistory.com
curl 활용해준 블로그도 있었는데 아무튼 감사합니다.
미리 말씀 드리지만 배우기 위해 보진 마세요..
과제 제출용으로 적당히 대충 쓴거라 하나도 도움 안됩니다 ㅠ.ㅠ
1. Web Server (NGNIX)
1. NCP 서버 생성
web server용 서버를 위해, NCP에서 서버를 생성하여 공인 IP를 부여했습니다. 공인 IP를 통해서 클라이언트가 도메인(혹은 IP 주소)을 통해 해당 서버에 요청을 보낼 수 있게 됩니다.
ACG는 편의상 모든 IP와 포트번호에 대해 접근할 수 있도록 설정하였습니다.
다음은 NGINX 설치 이후입니다.
1. NGINX 설정파일 적용
/etc/nginx/conf.d에는 nginx에 대한 설정파일이 존재합니다.
사용자 설정파일을 적용하기 위해서는, 해당 디렉토리 내의 default.conf 설정파일 대신 사용할 파일을 생성해야 합니다.
이때, 다음과 같은 절차를 거쳐야 합니다.
1) /etc/nginx/conf.d에 site-available, site-enabled 디렉토리 생성
sudo mkdir site-available
sudo mkdir site-enable
2) site-available 디렉토리 안에 test.conf 생성
sudo vi test.conf
test.conf의 자세한 내용은 후술 하겠습니다.
3) 심볼릭 링크 생성
sudo ln -s /etc/nginx/conf.d/sites-available/test.conf /etc/nginx/conf.d/sites-enabled/test.conf
2. 설정파일 test.conf 내용 수정
default.conf 파일과 같이, 웹 서버를 구성하는데 사용되는 기본 설정 파일입니다.
upstream was{
server 10.39.142.205:9090;
server localhost:9090;
}
server {
listen 80;
listen [::]:80;
server_name 175.106.92.250;
location / {
root html;
index index.html index.htm;
}
location /servlet {
proxy_pass http://was/servlet;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
index index.jsp;
}
}
upstream was{
server 10.39.142.205:9090;
server localhost:9090;
}
upstream 블록은 웹 서버가 클라이언트의 요청을 받아 다른 서버로 전달할 수 있도록 합니다. 해당 블록에는 다른 서버에 대한 연결 정보로 서버이름, IP Address, Port 번호를 지정할 수 있습니다.
변수로 was라는 이름을 사용하고, server 지시어에는 was의 비공인 ip와 로컬호스트를 작성합니다. "was"는 이후 location 블록에서 사용됩니다.
server 블록은 HTTP 서버의 설정을 정의합니다. 서버의 Port, 호스팅하는 도메인 이름, SSL 인증서 위치 등을 정의할 수 있습니다.
listen 지시어는 HTTP 서버가 수신 대기할 Port 번호입니다. 80으로 설정합니다.
server_name 지시어는 호스팅하는 도메인 이름을 정의합니다. 현재 NCP web server의 공인 IP인 175.106.92.250로 설정합니다.
location / {
root html;
index index.html index.htm;
}
location 블럭은 특정 URI 또는 URI 패턴에 대한 설정을 정의합니다. 특정 URI에 대한 캐싱, 프록시 패스, 인증 등의 설정을 포함할 수 있습니다.
그리고 root 지시어는 정적 파일에 대한 디렉토리 경로를 정의합니다.
따라서 location / {} 블럭은 175.106.92.250로 요청을 받았을 때, html 디렉토리 내에 존재하는 index.html을 클라이언트에게 반환하도록 설정하는 것입니다.
index 지시어는 디렉토리에 대한 색인 파일을 정의합니다. 정적 파일로 index.html 혹은 index.htm을 클라이언트에게 돌려줍니다.
location /servlet {
proxy_pass http://was/servlet;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
location / servlet {} 블럭은 175.106.92.250 / servlet 요청을 받았을 때의 절차를 정의 합니다.
web 서버가 해당 요청을 받았을 때, http://10.39.142.205:9090/servlet 경로로 요청을 전달합니다.
proxy_pass에서, "was"는 upstream 변수로 정의한 was에서 지정된 ip 주소로 치환됩니다.
2. nginx.conf 파일 수정
위에서 test.conf의 위치를 include에 경로로 적어줍니다.
이제 Web Server에서 WAS로 요청을 넘길 수 있게 됩니다.
2. WAS (Apache Tomcat)
1. NCP 서버 생성
클라이언트가 직접 WAS에 접근할 수 없도록 공인 IP를 부여하지 않았습니다.
여기서 서버 접속용 공인 IP가 필요한 이유는 위의 10.37.12.130 주소가 사설IP 주소이기 때문에 외부에서 식별할 수 없기 때문입니다. 여기서 외부는 클라우드 사용자인 본인도 포함입니다.
따라서, 포트 포워딩을 통해 서버 접속용 공인 IP와 외부 포트번호를 조합하여, 특정 사설IP를 가진 서버 및 PC에 연결할 수 있습니다.
포트번호를 2222로 설정하였습니다. 서버 접속용 IP와 해당 포트번호는 ssh 연결에 사용합니다.
다음은 Tomcat 설치 이후입니다.
2. server.xml 설정
Connector 태그를 통해 포트번호 "8080"을 "9090"으로 바꾸어 주었습니다.
appBase는 webapps여야 하며, 절대경로로 지정하였습니다.
3. 톰캣에 war배포하기
일단, webapps 디렉토리에서 ls를 한다면 다음과 같은 디렉토리들이 존재합니다.
위에서 appBase를 webapps로 지정 해주었을때, 참조할 수 있는 최상위 디렉토리는 ROOT입니다.
mkdir Servlet
cd ./Servlet
git clone https://github.com/0-tae/3tier_was_test.git
webapps 디렉토리 내에 Servlet 디렉토리를 만들어서, 미리 만들어둔 자바 프로젝트를 git hub repository로 생성하고, git clone하여 was 서버 내에 생성합니다.
해당 위치에서 ./gradlew build 명령어를 통해 프로젝트를 build합니다.
만약, Permission denied가 출력된다면 chmod 777 ./gradlew 명령어를 통해서 쓰기 권한을 부여합니다.
해당 위치에서 war파일을 확인할 수 있습니다.
mv Servlet-1.0-SNAPSHOT.war ROOT.war
mv ROOT.war /usr/local/lib/apache-tomcat-8.5.59/webapps
빌드해서 나온 war 파일을 ROOT.war로 변경한 뒤, webapps 디렉토리로 옮깁니다.
이때, 톰캣은 자동으로 war파일을 압축해제하여 해당 이름을 가진 디렉토리를 생성합니다.
WAS에서의 동적 처리를 위한 준비를 마쳤습니다.
3. DB Server (My SQL)
1. NCP 서버 생성
WAS와 비슷하게 설정하였습니다.
2. My SQL 설치
my sql은 도커로 설치하여 이용하였습니다.
docker run --name 3tier-mysql -e MYSQL_ROOT_PASSWORD=1234#7! -d -p 3306:3306 mysql:latest
3tier-mysql이라는 컨테이너 이름으로 3306 포트에 연결하여 최신 버전의 dokcer 이미지를 가져옵니다.
docker exec -it 3tier-mysql bash
mysql -u root -p // bash 상태
create database mytest // bash 상태
mysql 테스트를 위해, mytest라는 database를 생성하였습니다.
3tier 테스트
먼저 테스트용 index.html 파일과 test.js파일을 web server의 /etc/nginx/html 디렉토리에 생성합니다.
공인 IP를 입력하여 서버에 요청을 보낸다면, test.conf에서 설정한 대로 index.html 파일을 클라이언트에게 보여줍니다.
"DB에서 데이터 가져오기" 버튼을 클릭하면 위의 test 함수를 실행합니다.
여기서, ajax를 이용하여 http://{Public IP}/servlet 요청을 보냅니다. test.conf 설정대로라면, 해당 요청을 http://was/servlet으로 전달하게 됩니다. ajax 요청의 반환 값은 동적 처리된 데이터입니다.
다음은 자바 프로젝트 파일입니다.
package com.example.servlet;
import java.io.*;
import java.sql.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
@WebServlet(name = "servlet", urlPatterns = {"/servlet"})
public class HelloServlet extends HttpServlet {
private String message="DEFAULT MASSAGE";
public void init(){}
public void dbtest() {
Connection conn = null;
try {
// JDBC 드라이버 로딩
Class.forName("com.mysql.cj.jdbc.Driver");
// 데이터베이스 연결 설정
String url = "jdbc:mysql://10.37.60.194:3306/test";
String username = "root";
String password = "dydrkfl#7!";
conn = DriverManager.getConnection(url, username, password);
// 쿼리 실행
Statement stmt = conn.createStatement();
String sql = "SELECT * FROM testtable";
ResultSet rs = stmt.executeQuery(sql);
// 결과 출력
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
message="ID: " + id + ", Name: " + name;
}
// 연결 해제
conn.close();
} catch (Exception e) {
message="db error: "+e.toString();
e.printStackTrace();
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
dbtest();
PrintWriter out = response.getWriter();
out.println(message);
}
public void destroy() {
}
}
build.gradle에 dependency로 mysql을 설정합니다.
그리고 dbtest() 메소드를 통해 데이터베이스 연결을 구축하며 쿼리문을 날리고 결과 값을 얻어옵니다.
데이터 베이스에는 다음과 같이 저장되어 있습니다.
message 문자열을 build하여 PrintWriter의 println 메소드를 통해 값을 return 합니다.
따라서, ajax의 반환 값은 message가 됩니다.
결과적으로 message에 대한 결과를 웹페이지에서 얻어올 수 있게됩니다.