회원 웹 기능 - 홈 화면 추가

    홈 컨트롤러 추가

    • controller>HomeController.java 생성

    회원 관리용 홈

    • resources>templates>home.html 생성

    회원 웹 기능 - 등록

    회원 등록 폼 개발

    회원 등록 폼 컨트롤러

    • controller>MemberController.java 에 코드 추가 - @GetMapping(value = "/members/new")
     

    회원 등록 폼 HTML

    • resources>templates>members>createMemberForm.html 생성

     

    회원 등록 기능 개발

    회원 등록 컨트롤러 - 웹 등록 화면에서 데이터를 전달 받을 폼 객체

    • controller>MemberForm.java 생성

    회원 컨트롤러에서 회원을 실제 등록하는 기능

    • controller>MemberController.java 에 코드 추가 - @PostMapping(value = "/members/new")

     

    ✏️ @GetMapping : 서버의 리소스를 조회할 때

    ✏️ @PostMapping : 서버에 리소스를 등록(저장)할 때


    회원 웹 기능 - 조회

    회원 컨트롤러에서 조회 기능

    • controller>MemberController.java 에 코드 추가 - @GetMapping(value = "/members")

    회원 리스트 HTML

    • resources>templates>members>memberList.html 생성

     

    스프링 빈과 의존관계

    스프링 빈(Bean)

    스프링 컨테이너에 의해 관리되는 자바 객체(재사용 가능한 소프트웨어 컴포넌트)

     

    의존성 주입: DI(Dependency Injection)

    객체 의존관계를 외부에서 넣어주는 것

     

    • DI 방식
      1. 필드 주입
      2. setter 주입
      3. 생성자 주입
    // 1. 필드 주입
    @Autowired private MemberService memberService;
    
    
    // 2. setter 주입
    private MemberService memberService;
    
    @Autowired
    public void setMemberService(MemberService memberService) {
        this.memberService = memberService;
    }
    
    
    // 3. 생성자 주입
    private final MemberService memberService;
    
    @Autowired
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }

     

    ‼️ 의존관계가 실행 중에 동적으로 변하는 경우는 거의 없으므로 생성자 주입 권장


    스프링 빈을 등록하는 2가지 방법

     

    1. 컴포넌트 스캔과 자동 의존관계 설정

    회원 컨트롤러를 생성하고 의존관계 추가하기

    • Controller - controller>MemberController.java

    ✏️ @Autowired스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 넣어줌 / 생성자가 1개만 있으면 생략 가능

    ‼️ @Autowired를 통한 DI는 helloController, memberService 등과 같이 스프링이 관리하는 객체에서만 동작, 스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작하지 않음

    package hello.hello_spring.controller;
    
    import hello.hello_spring.service.MemberService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    
    @Controller
    public class MemberController {
    
        private final MemberService memberService;
    
        @Autowired
        public MemberController(MemberService memberService) {
            this.memberService = memberService;
        }
    }
    

     

    ➡️ 이렇게 객체 의존관계를 외부에서 넣어주는 것을 DI (Dependency Injection)

    이전 테스트에서는 개발자가 직접 주입했고, 여기서는 @Autowired를 통해 스프링이 주입해줌

     

     

    컴포넌트 스캔 원리

    • @Component 애노테이션이 있으면 스프링 빈으로 자동 등록

     

    • @Component를 포함하는 애노테이션
      • @Controller
      • @Service
      • @Repository

     

    회원 서비스 스프링 빈 등록

    @Service
    public class MemberService {
    
        private final MemberRepository memberRepository;
    
        // 외부에서 memberRepository를 넣어주도록 변경
        @Autowired
        public MemberService(MemberRepository memberRepository) {
            this.memberRepository = memberRepository;
        }

     

    회원 리포지토리 스프링 빈 등록

    @Repository
    public class MemoryMemberRepository implements MemberRepository{

     

     

    스프링 빈 등록 이미지

    • memberService 와 memberRepository 가 스프링 컨테이너에 스프링 빈으로 등록
    • 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때기본으로 싱글톤으로 등록(유일하게 하나만 등록해서 공유)
      ➡️ 같은 스프링 빈이면 모두 같은 인스턴스
    • 설정으로 싱글톤이 아니게 설정할 수 있지만특별한 경우를 제외하면 대부분 싱글톤을 사용

    2. 자바 코드로 직접 스프링 빈 등록

    • 회원 서비스와 회원 리포지토리의 @Service, @Repository, @Autowired 애노테이션 제거하고 진행
    • java>hello.hello_spring>SpringConfig.java 생성
    package hello.hello_spring;
    
    import hello.hello_spring.repository.MemoryMemberRepository;
    import hello.hello_spring.service.MemberService;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class SpringConfig {
    
        @Bean
        public MemberService memberService() {
            return new MemberService(memberRepository());
        }
    
        @Bean
        public MemoryMemberRepository memberRepository() {
            return new MemoryMemberRepository();
        }
    }

     

    ✔️ 실무에서 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용

    ✔️ 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록

    회원관리 예제 - 백엔드 개발

    비즈니스 요구사항 정리

    • 데이터: 회원ID, 이름
    • 기능: 회원 등록, 조회
    • 아직 데이터 저장소 선정 x -> 가상의 시나리오

     

    일반적인 웹 애플리케이션의 계층 구조

    • 컨트롤러: 웹 MVC의 컨트롤러 역할
    • 서비스: 핵심 비즈니스 로직 구현
    • 리포지토리: 데이터베이스에 접근, 도메인 객체를 DB에 저장하고 관리
    • 도메인: 비즈니스 도메인 객체, 예) 회원, 주문, 쿠폰 등등 주로 데이터베이스에 저장되고 관리됨

     

    클래스 의존관계

    • 인터페이스로 구현 클래스를 변경할 수 있도록 설계
    • 개발 진행을 위해서 초기 개발 단계에서는 구현체로 가벼운 메모리 기반의 데이터 저장소 사용

     


    회원 도메인, 리포지토리, 서비스 개발

    • Domain - domain>Member.java
    • Repository interface - repository>MemberRepository.java
    • Repository 메모리 구현체 - repository>MemoryMemberRepository.java
    • Service - service>MemberService.java

    ✔️ Service는 비즈니스에 의존적으로 설계(join, login 등)

     

    ✏️ Optional - 값이 null 일 때, null 그대로 반환하는 대신 optional로 감싸서 반환

    ✏️ implements 후 option + enter - @Override 가능

     


    회원 리포지토리, 서비스 테스트 케이스 작성

     

    개발한 기능을 실행해서 테스트 할 때, 1) main 메서드를 통해서 실행, 2) 웹 애플리케이션의 컨트롤러를 통해 실행

     

    ⚠️ 문제점 ⚠️

    1. 준비하고 실행하는데 오래 걸림
    2. 반복 실행하기 어려움
    3. 여러 테스트를 한번에 실행하기 어려움

    ➡️ JUnit이라는 자바의 프레임워크로 테스트를 실행해서 문제 해결

     

    ✔️ 테스트 클래스 생성 방법

    1. src>test>java 하위 폴더에 직접 테스트 클래스 생성
    2. 클래스에서 command + shift + t -> 테스트 클래스 생성

     

    ✔️ given / when / then 으로 테스트 케이스 작성하기

    • given: 주어진 상황
    • when: 실행
    • then: 결과

     

    ✏️ @AfterEach: 각 테스트가 종료될 때마다 메모리 DB에 저장된 데이터를 삭제

    @AfterEach
    public void afterEach() {
        repository.clearStore();
    }

    ‼️ 한번에 여러 테스트를 실행하면 메모리 DB에 직전 테스트 결과가 남을 수 있어, 이전 테스트로 인해 다음 테스트가 실패할 가능성 존재

    ‼️ 모든 테스트는 각각 독립적으로 실행되어야 함

    ‼️ 테스트 순서에 의존관계가 있는 것은 좋은 테스트가 아님

     

    ✏️ @BeforeEach: 각 테스트 실행 전에 호출되어 테스트가 서로 영향이 없도록 항상 새로운 객체를 생성하고, 의존관계도 새로 맺어줌

    @BeforeEach
    public void beforeEach() {
        memberRepository = new MemoryMemberRepository();
        memberService = new MemberService(memberRepository);
    }

     

    정적 컨텐츠

    스프링 부트 정적 컨텐츠 기능을 자동으로 제공 - static

    https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/html/spring-boot-features.html#boot-features-spring-mvc-static-content

     

    • resources/static/hello-static.html 생성
    <!DOCTYPE HTML>
    <html>
    <head>
        <title>static content</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </head>
    <body>
    정적 컨텐츠 입니다.
    </body>
    </html>

     

    • 실행 - http://localhost:8080/hello-static.html 

     

    정적 컨텐츠 이미지

     

    - 웹 브라우저에서 주소를 입력하면 내장 톰캣 서버에서 요청을 받고, hello-static.html의 요청이 왔다고 스프링 부트한테 넘김

    - 스프링 부트는 먼저 컨트롤러에서 hello-static 찾음

    - 없으면 resources/static 에서 hello-static.html 찾아서 웹 브라우저에 반환


    MVC와 템플릿 엔진

    • MVC: Model, View, Controller

     

    • Controller - helloController.java 에 추가
    @Controller
     public class HelloController {
         @GetMapping("hello-mvc")
         public String helloMvc(@RequestParam("name") String name, Model model) {
             model.addAttribute("name", name);
             return "hello-template";
         }
    }

     

    • View - resources/templates/hello-template.html 생성
    <html xmlns:th="http://www.thymeleaf.org">
    <body>
    <p th:text="'hello ' + ${name}">hello! empty</p>
    </body>
    </html>

     

    • 실행 - http://localhost:8080/hello-mvc?name=spring 

    MVC, 템플릿 엔진 이미지

    - 웹 브라우저에서 주소를 입력하면 내장 톰캣 서버에서 요청을 받고, hello-mvc의 요청이 왔다고 스프링 부트한테 넘김

    - 컨트롤러에 hello-mvc 가 매핑이 되어있으므로 hello-mvc 메서드 호출

    - hello-mvc?name=spring 이므로 값은 spring - model(name:spring)

    - retrun: hello-template이므로 viewResolver가 temlplates/hello-template.html을 템플릿 엔진에 넘김

    - 템플릿 엔진이 랜더링해서 변환한 HTML 반환


    API

    • @ResponseBody 문자 반환
    @Controller
     public class HelloController {
         @GetMapping("hello-string")
         @ResponseBody
         public String helloString(@RequestParam("name") String name) {
             return "hello " + name;
         }
     }

    - @ResponseBody를 사용하면 viewResolver를 사용하지 않음

     

    • 실행 - http://localhost:8080/hello-string?name=spring

    - HTTP의 BODY에 문자 내용을 직접 반환

     

    • @ResponseBody 객체 반환
    @Controller
    public class HelloController {
    	
        @GetMapping("hello-api")
        @ReponseBody
        public Hello helloApi(@RequestParam("name") String name) {
        	Hello hello = new Hello();
            hello.setName(name);
            return hello;
        }
        
        static class Hello {
        	private String name;
            
            pubilc String getName() {
            	return name;
            }
            
            public String setName(String name) {
            	this.name = name;
            }
        }
    }

    - Getter, Setter 필요

    - @ResponseBody를 사용

     

    • 실행 - http://localhost:8080/hello-api?name=spring

    - 객체를 반환하면 객체가 JSON으로 변환됨

     

     

    @ResponseBody 사용 원리

    - HTTP의 BODY에 문자 내용 직접 반환

    - viewResolver 대신에 HttpMessageConverter 가 동작

    - 기본 문자 처리(위의 문자 반환의 경우): StringHttpMessageConverter

    - 기본 객체 처리(위의 객체 반환의 경우): MappingJackson2HttpMessageConverter

    프로젝트 생성하기

    ✔️IDE: IntelliJ

     

    스프링 부트 스타터 사이트로 스프링 프로젝트 생성

    https://start.spring.io

    • 프로젝트 선택
      • Project: Gradle - Groovy
      • Spring Boot: 3.3.3
      • Language: Java
    • Metadata
      • Group: hello
      • Artifact: hello-spring
    • Dependencies
      • Spring Web
      • Thymeleaf(html을 만들어주는 템플릿 엔진)
    더보기

    Group - 기업명, 기업 도메인명 / Artifact - 빌드되면 나오는 결과물 = 프로젝트명

     

    • GENERATE > 압축 파일 풀기 > IntelliJ에서 파일 Open

     

    프로젝트 실행 및 빌드

    동작 확인

    • 기본 메인 클래스 실행
      - @SpringBootApplication: 스프링부트 애노테이션으로 톰캣이라는 웹서버를 내장하고 있어서 스트링부트 실행
      - 스프링부트 스타터 사이트에서 프로젝트를 생성하면 @SpringBootApplication 이 작성된 상태로 프로젝트가 생성됨 

    실행 로그에서 Tomcat 실행 확인 가능

     

    • http://localhost:8080로 이동하여 에러페이지로 간단하게 동작 확인


    ✚ IntelliJ로 자바 직접 실행

    • Gradle을 통해 실행하는 것이 기본 설정인데 이렇게 하면 실행속도가 느리므로 변경해주기
    • preferences > gradle > Build and run using, Run tests using -> IntelliJ IDEA 로 설정

     


    ✚ 라이브러리 살펴보기

    • Gradle은 의존관계가 있는 라이브러리를 함께 다운로드

    스프링부트 라이브러리

    • spring-boot-starter-web
      • spring-boot-starter-tomcat: 톰캣(웹서버)
      • spring-webmvc: 스프링 웹 MVC
    • spring-boot-starter-thymeleaf: 타임리프 템플릿 엔진(View)
    • spring-boot-starter(공통): 스프링 부트 + 스프링 코어 + 로깅
      • spring-boot
        • spring-core
      • spring-boot-starter-logging (로그로 출력해야 로그파일이 관리가 됨(심각한 에러 등))
        • logback, slf4j 

    테스트 라이브러리

    • spring-boot-starter-test
      • junit: 테스트 프레임워크
      • mockito: 목 라이브러리
      • assertj: 테스트 코드를 좀 더 편하게 작성하게 도와주는 라이브러리
      • spring-test: 스프링 통합 테스트 지원

    View 환경설정

    Welcom Page 만들기

    • src > main > resources > static > index.html 생성
    <!DOCTYPE HTML>
    <html>
    <head>
        <title>Hello</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </head>
    <body>
    Hello
    <a href="/hello">hello</a>
    </body>
    </html>

    ✚ 스프링 부트가 제공하는 Welcome Page 기능

     

    •  java > hello.hello_spring > controller 패키지 생성 > helloController.java 생성
    package hello.hello_spring.controller;
    
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    
    @Controller
    public class helloController {
        @GetMapping("hello")
        public String hello(Model model) {
            model.addAttribute("data", "hello!!");
            return "hello";
        }
    
    }

     

     

    • resources > templates > hello.html 생성
    <!DOCTYPE HTML>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>Hello</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </head>
    <body>
    <p th:text="'안녕하세요. ' + ${data}" >안녕하세요. 손님</p>
    </body>
    </html>

     

    - data : model 에서의 key 값 (즉, hello!!)

     

     

    동작 환경 그림

    return:hello - templates 밑의 hello를 찾아서 랜더링

    ➡️ 컨트롤러에서 리턴 값으로 문자를 반환하면 뷰 리졸버(veiwResolver)가 화면을 찾아서 처리

    - 스프링 부트 템플릿 엔진 기본 veiwName 매핑

    - resource:templates/ + {ViewName} + .html


    프로젝트 빌드하고 실행하기

    • 콘솔로 이동
    ./gradlew build
    
    cd build/libs
    
    java -jar hello-spring-0.0.1-SNAPSHOT.jar

     

    • 실행 확인하기

    프로젝트 배포하기

    1. AWS RDS의 MySQL을 연결
      • 그 동안은 H2를 사용했기 때문에, 서비스를 내렸다 올리면 모든 데이터가 초기화되었음
        ➡️ 데이터를 클라우드에 저장하여 서비스를 껐다 켜도 데이터가 유지되도록 함
    2. AWS EC2에 배포
      • 누구나 서비스에 접속할 수 있게 하려면 원격으로 항상 작동하는 컴퓨터 필요
    3. 도메인 붙이고 카카오톡으로 공유하기
      • OG 태그: 카카오톡으로 링크를 공유할 때, 자동으로 이미지, 제목, 내용을 가져오게 함

     

     

    AWS RDS 구매하고 MySQL 세팅하기

     

    RDS 구매하기

    1. AWS에 접속하여 RDS 검색
    2. 데이터베이스 생성 > 표준 생성 > MySQL > 프리 티어 선택
    3. 설정 입력 - DB 인스턴스 식별자: 원하는 이름 작성 / 마스터 사용자 이름, 암호: DB 접속용으로 만들고 싶은 계정의 아이디, 비밀번호
    4. DB 인스턴스 크기, 스토리지 설정 그대로
    5. 연결 > 추가 연결 구성 탭 클릭 후 다음과 같이 설정
      - 퍼블릭 액세스 기능: "예" (이 설저이 되어 있어야 MySQL 연결 가능)
      - VPC 보안 그룹: "새로 생성"
      - 새 VPC 보안 그룹 이름: sprinboot-db-security
      - 가용 영역: 옵션 중 아무거나
    6. 추가 구성 > 초기 데이터베이스 이름에 "myselectshop" 입력 후 데이터베이스 생성 클릭

     

    RDS 포트 열어주기

    1. 생성한 데이터베이스 클릭 > 연결 & 보안 > 보안 > VPC 보안 그룹의 springboot-db-security > 보안 그룹 ID 클릭
    2. 인바인드 규칙 편집 > 소스 > 위치 무관 -> 0.0.0.0, :/0 생성 후 "규칙 저장" 클릭

     

    IntelliJ에서 확인

    1. RDS 앤드포인트 확인 후 드래그하여 복사
    2. <나만의 셀렉샵> 프로젝트 열기 > 우측 Database 탭 > Data Source > MySQL
      - Name: 생성한 데이터베이스 이름
      - Host: 앤드포인트
      - User: Username
      - Password: 비밀번호
      - Database: myselectshop
    3. Test Connection > 성공적으로 연결되면 OK

     

    스프링부트를 MySQL과 연결하기

    - 스프링부트 설정의 대부분은 application.properties 에서 관리

    spring.datasource.url=jdbc:mysql://나의앤드포인트:3306/myselectshop
    spring.datasource.username=나의USERNAME
    spring.datasource.password=나의패스워드
    spring.jpa.hibernate.ddl-auto=update

     

     

    OG 태그

    <meta property="og:title" content="00만의 셀렉샵">
    <meta property="og:description" content="관심상품을 선택하고, 최저가 알림을 확인해보세요!">
    <meta property="og:image" content="images/og_selectshop.png">

     

     

     

    AWS EC2 준비하고 배포하기

     

    SSH(Secure Shell Protocol)

    - 다른 컴퓨터에 접속할 때 사용하는 프로그램으로 다른 프로그램보다 보안이 상대적으로 뛰어남

    - 접속할 컴퓨터의 22번 포트가 열려있어야 접속 가능

    - AWS EC2의 경우 이미 22번 포트가 열려있음

     

     

    리눅스 명령어

    ls: 내 위치의 모든 파일을 보여줌
    
    pwd: 내 위치(폴더의 경로)를 알려줌
    
    mkdir: 내 위치 아래에 폴더 하나 생성
    
    cd [이동할 곳]: [이동랗 곳] 폴더로 이동
    
    cd ..: 상위 폴더로 이동
    
    cp -r [복사할 것] [붙여넣기 할 것]: 복사 붙여넣기
    
    rm -rf: 삭제
    
    sudo [실행할 명령어]: 관리자 권한으로 명령어 실행
    
    sudo su: 관리가 권한으로 들어감 (나올 땐 exit)

     

     

    AWS EC2 서버 구매 

    https://ap-northeast-2.console.aws.amazon.com/ec2/home?region=ap-northeast-2#Home:

     

    AWS EC2 접속

    • Mac OS의 경우 ssh가 있어서 명령어로 AWS EC2에 바로 접근 가능
      # Keypair 접근 권한 바꿔주기 
      sudo chmod 400 받은키페어경로
      
      # SSH로 접속하기 
      ssh -i 받은키페어 ubuntu@AWS에적힌내아이피

     

    배포 파일 빌드

    1. 프로젝트 실행 후 우측 탭 중 "Gradle" 선택
    2. Tasks > build > build 더블 클릭
    3. 좌측 build 폴더 > libs 아래 .jar 확장자로 끝나는 파일 생기면 빌드 성공

     

    OpenJDK 설치

    • ubuntu 안에 설치
    sudo apt-get update
    sudo apt-get install openjdk-17-jdk
    java -version

     

     

     

    Filezilla 이용하여 배포 파일 업로드

    1. Filezilla 실행 후 왼쪽 상단 사이트 관리자 클릭
    2. 새 사이트 생성 후 연결
      - 프로토콜: SFTP - SSH File Transfer Protocol
      - 호스트: EC2 퍼블릭 IPv4 주소
      - 로그온 유형: 키 파일
      - 사용자: ubuntu
      - 키 파일: EC2 인스턴스 생성 시 생성한 .pem 파일
    3. 마우스로 드래그하여 .jar 파일 업로드

     

    스프링부트 작동시키기

    cd jar파일상위폴더
    
    java -jar jar파일명.jar

     

    더보기

    ⚠️ 오류 발생 ⚠️

     

    Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.

     

    ‼️ 해결 방법 ‼️

    lsof -i tcp:8080 으로 8080 포트 사용 중인 프로세스 확인

    sudo kill -9 [PID] 로 해당 프로세스 종료

     

     


    AWS에서 80, 8080 포트 열어주기

    • AWS EC2 에서도 자체적으로 포트를 열고 닫을 수 있게 관리하고 있음
      ➡️ AWS EC2 Security Group 에서 인바운드 요청 포트 열어줘야 함 
    • EC2 관리 콘솔 > 보안그룹 > 인바운드 규칙 편집 > 8080포트 추가
      - 80포트: HTTP 접속을 위한 기본 포트
      - 8080포트: 스프링부트 기본 포트

     

    포트포워딩(Port Forwarding)

    • http 요청에서는 80포트가 기본이기 때문에 굳이 :80을 붙이지 않아도 자동으로 연결
    • 지금은 8080 포트에서 웹 서비스가 실행되고 있기 때문에, 매번 :8080 이라고 뒤에 포트 번호 입력해야함
    • 포트 번호를 입력하지 않아도 자동으로 접속되기 위해, 80포트로 오는 요청을 8080 포트로 전달하게 함 ➡️ 포트포워딩

     

    포트 번호 없애기

    1. 돌아가고 있던 서비스 종료하고 터미널에 포트포워딩 룰 입력
    2. 다시 서비스 시작
      sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
    3. 포트 번호 입력 없이 웹 브라우저에서 접속
      java -jar JAR파일명.jar

     

     

    SSH 접속을 끊어도 서버가 계속 돌게 하기

    • 현재 상황: SSH 접속을 끊으면 프로세스가 종료되면서 서버가 돌아가지 않음
    • 원격 접속을 종료하더라도 서버가 계속 돌아가게 하기
      # 아래의 명령어로 실행하면 된다
      nohup java -jar JAR파일명.jar &
    • 서버 종료하기(강제 종료)
      # 아래 명령어로 미리 pid 값(프로세스 번호)을 본다
      ps -ef | grep java
      
      # 아래 명령어로 특정 프로세스를 죽인다
      kill -9 [pid값]
    • 다시 켜기
      # 아래의 명령어로 실행하면 된다
      nohup java -jar JAR파일명.jar &​
    • SSH 접속 종료 후 다시 접속해보기

     

     

    도메인 붙이고 카카오톡에 공유

    • 도메인 구매: 네임서버릉 운영해주는 업체에, IP와 도메인 매칭 유지비를 내는 것
    1. '가비아'에서 도매인 구매 후 관리툴 > 도메인 연결 > DNS 설정 클릭
    2. 호스트 이름: @, IP 주소: IP 주소 입력 후 10분 정도 대기
    3. 내 도메인으로 접근하여 접속하고 카카오톡으로 공유하기

     

    + Recent posts