반응형
반응형
import java.util.List;
import java.util.function.Supplier;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import com.lsj.blog.model.RoleType;
import com.lsj.blog.repository.UserRepository;


@GetMapping("/dummy/user/{id}")
public BlogUser detail(@PathVariable int id) { // PathVariable은 들어온 id값에 따른 동적 처리 {id}


    // BlogUser user = userRepository.findById(id); // findById의 return 타입은 Optional
                                                    // → 자바에서 DB 데이터를 못찾아오게 되면 user가 null이 되어 return이 되기 때문에
                                                    // Optional로 객체를 감싸서 가져올테니 null인지 아닌지 판단해서 return 해라
    /** 방법1 **/
    // userRepository.findById(id).get(); // null 그런거 상관없이 가져오겠다. (위험) 

    /**  방법 2
    BlogUser user = userRepository.findById(id).orElseGet(new Supplier<BlogUser>(){
        @Override
        public BlogUser get() { // 값이 없는 경우 BlogUser 객체 생성해 주입 (Null 가능성은 없음)
            return new BlogUser();
        }
    });
    **/

    /** 방법3 (선호) 해당 에러 발생시 Throw **/
    BlogUser user = userRepository.findById(id).orElseThrow(new Supplier<IllegalArgumentException>(){
        @Override
        public IllegalArgumentException get() {
            return new IllegalArgumentException("해당 유저는 없습니다. id : " + id);
        }
    });

    return user;
}

// 페이지리스트 모두 출력
@GetMapping("/dummy/list")
public List<BlogUser> list(){
    return userRepository.findAll();
}

// 페이지네이션
// size → 보여줄 개수
// sort → order by 할 필드
// direction  → 오름차순 또는 내림차순
// dummy/list/page?page=0 일시 id 3번, 2번 노출  | page=1로 호출시 id 1번 노출
// 아무것도 입력안 할시 ?page=0과 동일
@GetMapping("dummy/list/page")
public Page<BlogUser> pageList(@PageableDefault(size=2, sort="id", direction = Sort.Direction.DESC) Pageable pageable){
    Page<BlogUser> users = userRepository.findAll(pageable);
    return users;
}

 

반응형
반응형
package com.lsj.blog;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import com.lsj.blog.model.RoleType;
import com.lsj.blog.repository.UserRepository;

@RestController
public class DummyController {

	@Autowired // DI
	private UserRepository userRepository;
	
	@PostMapping("/dummy/join")
	public String join(BlogUser user) { 
		
		//user.setRole("user"); // @DynamicInsert처럼 계속 어노테이션을 붙히다보면 어노테이션 지옥에 빠지기 때문에 직접 Setter에 주입해 어노테이션을 줄일 수 있지만 실수할 수 있다.
		user.setRole(RoleType.USER); // Enum을 이용한 방식을 통해 Setter 주입 실수를 방지할 수 있다. 
		userRepository.save(user); // UserRepostiory에 save하면 DB 테이블에 insert가 된다.
		
		return "회원가입이 완료되었습니다.";
	}
}

DummyController.java

 

package com.lsj.blog.model;

//데이터 강제할 수 있다. (데이터의 도메인화 → 강제)
public enum RoleType {
	USER, 
	ADMIN 
}

RoleType.java

 

package com.lsj.blog.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.lsj.blog.BlogUser;

// extends JapRepository가 있는 경우 @Repository 생략가능
// JpaRepostiory는 다양한 기능을 가지고 있다. findAll (모든 레코드 select) 페이징해서 보내줄 수 있는 기능도 존재
public interface UserRepository extends JpaRepository<BlogUser, Integer>{ // BlogUser의 Repository이고 PK는 Integer이다.
	
}

UserRepository.java

 

package com.lsj.blog;

import java.sql.Timestamp;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.DynamicInsert;

import com.lsj.blog.model.RoleType;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/** 하기 어노테이션 사용하려면 Javax Persistence API Gradle 추가 필요 **/
@DynamicInsert // null 인 값일 때는 무시하고 Default값으로 넣어준다
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity // 하기 필드 기준으로 DB에  User 테이블을 생성하라는 의미
public class BlogUser {

	@Id // Primary key
	@GeneratedValue(strategy = GenerationType.IDENTITY) // 프로젝트에서 연결된 DB의 넘버링 전략을 따라간다.
	// → 즉, DB에 따라 AutoIncrement 또는 Sequence가 결정 되어서 알아서 만들어준다. (자동 증가 PK 필요함으로 이와 같은 행동 함) 
	// (MySql에서는 AutoIncrement, Oracle에서는 Sequence 사용)
	private int id;
	
	@Column(nullable = false, length = 30, unique=true) // null 방지 및 길이 30 + 중복값 방지
	private String username;
	
	@ColumnDefault(" 'no password' ") //→ @DynamicInsert 와 같이 사용한다. null일시에는 ColumnDefault에 선언된 값(no password)으로 넣어준다.   
	@Column(nullable = true, length = 100) 
	private String password;

	@Column(nullable = false, length = 50) 
	private String email;
	
	//@ColumnDefault("'user'") // → Column Default 값 String이기 때문에 ' ' 안에 넣어야한다.
	//private String role; // Enum을 
	
	@Enumerated(EnumType.STRING) // DB에는 RoleType이라는 타입이 없기 때문에 String 이라고 선언
	private RoleType role;
	
	@CreationTimestamp // 현재 시각 바로 자동 입력
	private Timestamp createDate;
	
}


/**
위와 같은 엔터티일 때 세이브할 데이터 형식 예제
{
    "username" : "lee6",
    "email" : "abc@naver.com"
}

결과 → 2	22/12/03 12:31:26.986000000	tjdwo37@naver.com	no password	USER	lee6
**/

BlogUser.java

반응형
반응형

📝Tomcat 큰 3가지 구성

Coyote : Tomcat TCP 프로토콜 지원
Catalina : Java Servlet을 호스팅 해준다.
Jasper : JSP 페이지 요청 처리 Servlet

 

📝톰캣 동작 구조

Tomcat Server가 그 밑에 Service 객체를 생성한다 (그 하위에는 Engine, Connector(호출 포트), Host, Context(URI Mapping) 등이 존재)

HTTP 통신 요청 → 호출 포트에 해당하는 Connector 연결 → Service → Engine → Host → Context(기본적으로 webapps에 있는 곳 참조해 프로젝트 URI Mapping → 프로젝트 내 web.xml 읽기 → 프로젝트 내 web.xml 기반으로 프로젝트 URI 매핑

 

 


하나의 Server에는 여러개 Service가 존재할 수 있다.
하나의 Service에는 1개의 Engine과 여러개의 Connector로 구성
하나의 Engine에는 여러개 Host 존재할 수 있다.
하나의 Host에는 여러개 Context가 존재할 수 있습니다.

 

Tomcat Server → Engine(Connector로 통해 전달) → Host → Context 

[Tomcat에서는 server.xml에 적혀있는 내용을 가지고 객체를 만드는 거라고 생각하면 된다. 그렇기 때문에 Connector에 포트번호를 적어두면 어떤 Service를 이용할지 방향을 알려준다]

 

📝Server

port : Shutdown 명령을 보낼 수 있는 TCP/IP 주소

<Server port="8005" shutdown="SHUTDOWN">

 

📝Service

Serivce의 유일한 이름으로 Log를 남길 때 사용한다 (Catalina.out)

<Service name="Catalina">

 

 

📝Connector

 

특정 TCP port에서 request들을 listen해 engine으로 보내준다.

  • port
    • 리슨할 포트
  • protocol
    • TCP/IP 방식 
  • HTTP/1.1
    • 기본적으로 Connection당 하나의 요청을 처리 하도록 설계 동시 전송이 불가능하고 요청과 응답이 순차적으로 이뤄진다
  • HTTP/2
    • HTTP1.1을 완전하게 재작성한 것이 아니라 프로토콜의 성능에 초첨을 맞춰 수정한 버전 기본적으로 connection 한 개로 동시에 여러 개의 메시지를 주고 받을 수 있으며, 응답은 순서에 상관없이 stream으로 주고 받는다
  • AJP
    • "Apache JServ Protocol"의 약자로, Tomcat과 웹 서버(주로 Apache) 간의 통신을 위한 프로토콜로 Web서버인 Apache에서 어떤 포트를 들어오면 포트포워딩할 지에 대한 포트 설정을하고 Tomcat도 이에 대한 걸 받기 위한 프로토콜 설정 및 포트 개방을 한다
<!-- Apache 설정 -->
<VirtualHost *:80>
    ServerName yourdomain.com
    # 기타 설정

    ProxyPass / ajp://localhost:8009/    # Tomcat과의 AJP 연결 설정
    ProxyPassReverse / ajp://localhost:8009/
</VirtualHost>

<!-- Tomcat 설정 -->
<Connector protocol="AJP/1.3" port="8009" redirectPort="8443" />


위 프로토콜의 동작 방식 설정
- BIO : Tomcat 7 기본 방식 하나의 Thread가 하나의 Connection을 담당
- NIO :  Tomcat 8.5 기본 방식 하나의 Thread가 하나 이상의 Connection을 담당
- APR :  10.x 버전 부터 ARP 방식 삭제

<Connector port="7104" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="7004" URLEncoding="UTF-8" />

 

 

📝Thread Pool 설정

maxThreads : Connector가 생성할 수 있는 최대 Thread 수
maxConnections : 동시 처리 가능한 최대 Connection 수
maxSpareThreads : 최소로 실행을 유지할 thread 수
acceptCount : thread가 꽉 찼을 때 queue에 저장 가능한 최대 request 수

Thread Pool
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150", maxConnections >
공유 Thread Poll
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>

 

 

📝 Engine

name : Engine의 유일한 이름으로 Log를 남길 때 사용한다.
defaultHost ?

<Engine name="Catalina" defaultHost="localhost">

 

 

📝Host

name : 유일한 가상 Host명 (http://hostname/~)
appBase : app 폴더 (default webapps) Host마다 다른 appBase를 지정할 수 있다. (여러개 Domain 효율적 관리가능)
autoDeploy : appBase에 변동사항이 있을 때 자동으로 Deploy(배포) 해준다.
unpackWARs : war파일 deploy 설정 여부

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

 

 

📝Context

Host안에 있으며 하나의 WebApplication이며 주로 .war 형태로 배포됩니다.

docBase : 호출할 경로 URI이다. (/ABC/testing.jsp 호출시 /webapps/DEF/testing.jsp를 호출하게 된다.)

path : 실제 호출시킬 경로이다

만약 Context가 없으면 기본적으로 docBase는 webapps안에 있는 폴더 이름을 따라가게 된다.

즉, webapps/ABC 폴더가 존재시 /ABC/ 이런식으로 호출함

<Host name="localhost" appBase="webapps"
            unpackWARs="true" autoDeploy="true">
  <Context docBase="ABC" path="/DEF" reloadable="true"></Context>

 

 

 

 

🔗 참고 및 출처

https://velog.io/@hyunjae-lee/Tomcat-2-%EA%B5%AC%EC%A1%B0

 

Tomcat - (2) 구조

Tomcat의 구조에 대해 자세히 알아봅니다.

velog.io

 

https://bogyum-uncle.tistory.com/m/219

 

[Tomcat] server.xml 구조

톰캣의 server.xml 은 메인 설정 파일이며, Tomcat startup 초기 설정을 명세하는 책임이 있음 1. server.xml 태그 예시 2. 태그 상세 태그 설명 Server root element, shutdown port 지정, 전체 설정파일의..

bogyum-uncle.tistory.com

https://ijbgo.tistory.com/m/26

 

HTTP/1.1 VS HTTP/2

HTTP/1.1 동작 방식 HTTP/1.1는 기본적으로 Connection당 하나의 요청을 처리 하도록 설계동시 전송이 불가능하고 요청과 응답이 순차적으로 이뤄짐HTTP 문서 안에 포함된 다수의 리소스 (Images, CSS, Script)

ijbgo.tistory.com


https://velog.io/@wiostz98kr/HTTP1.1%EA%B3%BC-HTTP2.0%EC%9D%98-%EC%B0%A8%EC%9D%B4-e2v4x4t1

 

반응형
반응형

📝VPS

하나의 물리서버를 여러 개의 가상 서버로 쪼개어 사용하는 것을 의미합니다

 

📝언리얼 엔진  

미국의 에픽게임즈에서 개발한 3차원 게임 엔진

 

📝헥스(Hex)

헥스(Hex)16진수를 의미하며 헥스코드RGB값을 16진수로 표현하는데 사용됩니다 → FF00FF

 

📝커널

소프트웨어가 컴퓨터에서 수행되기 위해서는 메모리에 해당 프로그램이 있어야하는데 운영체제도 마찬가지로 전원이 켜짐과 동시에 메모리에 올라가야 동작한다. 하지만 운영체제처럼 규모가 큰 경우 모두 올라가면 메모리 공간 낭비가 심할 것이다 따라서 운영체제중 항상 필요한 부분을 전원이 켜짐과 동시에 메모리에 올려놓고 그렇지 않은 부분은 필요할 때 메모리에 올려 사용한다. 이때 메모리에 상주하는 운영체제의 부분을 커널이라고 하며 좁은 의미의 운영체제이다.

 

📝CGI

CGI란 공통 게이트웨이 인터페이스(Common Gateway Interface)의 약어로 웹서버와 외부 프로그램 사이에서 정보를 주고받는 방법이나 규약입니다

웹의 초기 단계에서 많이 사용 로서 CGI 프로그램은 Pyhton, Perl, Ruby 따위로 작성한 스크립트이며 성능, 보안, 스케일링, 유지보수 등에 문제로 사라지게 되었다프론트랑 백엔드 통신하는 것과 비슷한 역할을 하기 때문에 크게 보면 Rest API도 이에 해당한다고 볼 수 있다

 

 

반응형
반응형

📝해시

데이터를 value에 두고 인덱스(key)를 만든 형태로 "key:value" 데이터 구조를 가지게 된다 시간복잡도가 O(1) 로 매우 빠르다

 

📝해싱

해시의 키를 이용해 값을 구하는 작업을 의미한다

 

📝해시 테이블

해시(key, value)로 되어있는 자료구조로 Map이 있다

 

📝해시함수

해싱할 때 필요한 함수를 의미한다 예를 들면 HashMap에서 Key를 이용해 Value를 구하는 걸 의미한다

 

📝해시값

해시함수를 거쳐서 나온 값

 

📝SSL 인증서

SSL(Secure Sockets Layer) 인증서는 웹사이트의 신원을 확인하는 디지털 인증서이며 SSL 기술을 이용하여 서버에 전송

되는 정보를 암호화 이 포맷은 적합한 암호 해독 키로만 판독 가능한 포맷으로 되돌릴 수 있습니다.
사용자의 웹브라우저와 인터넷 사이트의 웹서버간 암호화 통신을 가능하게 하는 제3의 신뢰기관이 인증한 인증서  웹브라우저와 서버간 암호화 통신을 위한 프로토콜

 

📝SHA-256 (Secure Hash Algorithm 256)

단방향 암호화 방식으로 복호화가 되지 않는다
어떤 길이의 값을 입력하더라도 256비트의 고정된 결과값을 출력한다
대표적으로 외부로 유출되면 안되는 유저들의 패스워드 같은 것들을 DB에 저장을 할 때 그대로 저장하기 보다는 암호화를 한 뒤 저장을 한다
복호화가 필요한 데이터는 SHA256이 아닌 다른 방식으로 암호화 시키는 것을 추천한다

 

📝RSA

비대칭키 암호화 방식으로 암호화할 때 키와 복호화할 때 키가 다르다 
암호화할 때 키를 "공개키", 복호화할 때 키를 "개인키" 클라이언트가 가지고 있는 "공개키"로 데이터를 암호화하여, 서버로 전달한다

 

📝AES (Advanced Encryption Standard)

대칭키 알고리즘으로 "대칭키" 하나로 암호화 및 복호화 모두 진행하고 문자열 길이에 제약이 없다

 

📝솔트 (Salt)

솔트값은 랜덤으로 생성되며 길이는 어느 것이든 될 수 있다.

솔트값은 평문 암호에 추가되는 형태로 위에 나온 해시함수들의 암호화를 더 보완해줄 수 있다

솔트는 최소 128bit 정도 되어야 안전하다

 

  • SHA256 = 비밀번호 + 솔트값(암호값)
    • 비밀번호 = 1234abc
    • E1F53135E559C253 = 솔트값
    • 1234abcE1F53135E559C253 (비밀번호 + 솔트값) → SHA256 → EFA123JQVZ4FJ6PROW…. (해시된 값)
반응형
반응형

- 톰캣 포트 변경

${tomcat 설치경로}/conf/server.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at
...
-->
...
<Server port="8005" shutdown="SHUTDOWN">
...

    <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000"
               redirectPort="8443" />

....

      </Host>
    </Engine>
  </Service>
</Server>

Connector port="8080" → Connector port="${바꿀 포트번호}" 로 변경

 

SSL 인증서 발급

 

 

 

반응형
반응형

📝GraphQL

 

GraphQL은 페이스북이 2012년에 개발하여 2015년에 공개적으로 발표된 데이터 질의어이다

REST API는 기능이 추가될 때 마다 호출해야할 HTTP URL이 많아지고 클라이언트의 코드가 점점 복잡해지고있고 이 부분을 해결하기 위해서 만들어졌다 → 간결한 형식의 요청으로 유지보수가 편해진다

Front End단에서 내가 원하는 데이터만 요청이 가능하기 때문에 효율적이지만 중간에 GraphQL에 대한 호출 형식을 정해줘야하기 때문에 API 유지관리자의 경우 GraphQL 스키마를 작성하기 위한 일을 해야한다

 

// 호출 방식
query {
  user(id: 1) {
    name
    address
  }
}
// 응답
{
  "data": {
    "person": {
      "name": "martin",
      "address" : "seoul
    }
  }
}

 

 

📝모놀리식 아키텍처 (Monolithic Architecture)

컴포넌트로 구분이 안 되어 있고 하나의 서비스로 돌아간다 그렇기 때문에 작은 수정에도 시스템 전체를 빌드해야하고 테스트 시간 또한 길어지고 하나의 서비스가 모든 서비스에 영향을 준다

예를 들어 이벤트 서비스가 추가될 때 트래픽이 몰려서 서버가 죽으면 다른 서비스도 마비가 된다

또한 하지만 시스템이 커지기 시작하고 여러 컴포넌트들이 더해지면 문제가 발생하게 된다

하지만 하나의 컴포넌트이기 때문에 여러 설정을 할 필요 없어서 작은 볼륨의 시스템 개발시에 매우 유용하다.

 

간단한 예제로는 네이버를 만들면 네이버에는 네이버 쇼핑, 검색, 지식 IN 등이 있는데 이거를 하나의 프로젝트에 넣어서 관리하는 형태이다

 

📝Micro Service Architecture (MSA)

기능별로 여러 컴포넌트들로 나눈 형태이다

타 컴포넌트와 의존성이 없기 때문에 서버가 하나 죽더라도 나머지 서비스는 작동하게 된다

트래픽이 가장 많은 서비스에 서버를 개별적으로 증설이 가능하기 때문에 비용적 측면에서도 이점이 있다.

→ Monolithic의 경우는 하나의 컴포넌트이기 때문에 어떤 서비스가 트래픽이 많아 그 부분만 증가시키려고 해도 똑같은 서버를 하나 더 증설하는 수밖에 없다 (만약 주문 서비스에 고성능의 서버 5대가 필요할 경우 MSA의 경우 주문 서비스 5대 분량의 서버만 증설하면 되지만 Monolithic의 경우 모든 서비스를 받쳐줄 수 있는 성능의 서버가 기본이 되고 추가적으로 필요한 성능을 더 추가하거나하면 어마무시하게 비싸지게 된다)

 

MSA에는 Multi-Repo와 Monorepo 방식이 존재한다

 

📝Multi-Repo

다중 저장소로 네이버로 치면 네이버쇼핑 프로젝트, 네이버 검색 프로젝트, 네이버 지식 IN 프로젝트가 따로 존재하는 것이다 이럴 경우 MSA조건에 합당하지만 서로간의 리소스(package.json, 공통 모듈 등)는 공유 할 수 없다

 

📝Monorepo

하나의 코드 베이스 내에서 여러 프로젝트를 관리한다 실제로 거대한 프로젝트가 있고 그 안에 여러개로 나눈 형태이다  물론 MSA처럼 개별적으로 돌아가고 Multi-Repo에서는 서로간의 리소스를 공유할 수 없지만 Monorepo는 거대한 프로젝트 안에서 리소스(package.json, 공통 모듈 등)를 공유할 수 있다

 

 

MSA가 유행하고 있지만 꼭 정답은 아니고 프로젝트 특성 및 현재 상황에 따라 적절한 아키텍처를 선택해야한다.

 

 

📝B2B 

B2B 영업은 기업 대 기업(Business to Business)의 약자로 기업 간의 거래를 위한 영업 방식입니다.

고객은 회사이고 상품 수량이 많습니다 (인력 포함)

예를 들어 기업이 사용할 솔루션을 개발해서 판매하거나 개발할 때 인력이 필요해 SI 인력을 보내는 것도 포함됩니다

 

📝B2C

B2C 영업은 기업 대 소비자(Business to Customer)  즉, 소비자를 대상으로한 영업방식입니다

예를 들어서 일반인들이 사용하는 배달의민족, 네이버 포털와 같은 서비스 업들이 있습니다

 

 

🔗 참고 및 출처

http://clipsoft.co.kr/wp/blog/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98msa-%EA%B0%9C%EB%85%90/

 

마이크로서비스 아키텍처(MSA) 개념 소개 - CLIPSOFT

작성자 : 이응호 과장   마이크로서비스 아키텍처(MSA) 개념 소개   프리랜서로 일하고 있는 지인이 최근 구직을 하고 있었습니다. 그러면서 하는 말이 요즘 IT업계 구직시장에서 최고의 화두가 M

clipsoft.co.kr

https://medium.com/@magenta2127/monorepo-vs-multi-repo-vs-monolith-7c4a5f476009

 

반응형
반응형

톰캣기반으로 설명했습니다

 

📝1. Java 경로 확인

  1. 내가 실제 사용하는 jdk 위치 확인
    • alternatives --config java
    • 내 기준으로 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.322.b06-11.el8.x86_64/jre/bin/java 라는 path 노출

 

📝2. 1024 미만 포트 권한 주기

  1. 1024 미만 포트 사용권한 부여
    • setcap 'cap_net_bind_service=+ep' /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.322.b06-11.el8.x86_64/jre/bin/java →  (jdk는 1024 포트 미만을 사용할 수 있다)
  2. 부여된 권한 체크
    • getcap /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.322.b06-11.el8.x86_64/jre/bin/java
  3. 톰캣 실행
    • /usr/bin/java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory (에러 발생)

 

📝3. libjli.so path 다시 잡아주기 (에러 발생시)

  1. vi /etc/ld.so.conf.d/java.conf (파일 없을시 생성)
  2. /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.322.b06-11.el8.x86_64/lib/amd64/jli 내용 추가 
  3. 위에 수정 내용 서버에 적용하기
    • ldconfig

 

📝4. 톰캣 기동

반응형
반응형

📝테크리드(Tech Lead)

주로 소프트웨어 개발 팀에서 기술적 측면에서 팀을 이끄는 역할을 말합니다

프로젝트의 기술적 방향을 제시하고 팀원들을 조직하며 코드 리뷰를 수행하고 프로젝트의 기술적인 책임

 

📝CTO

기술 책임자로서 기업이나 조직에서 기술 전략의 주도를 맡고 있는 직위입니다 CTO는 기술적인 측면에서 기업의 비전을 이끌어 가며 기술적 결정을 내립니다 주로 연구 및 개발, 기술적 혁신, 시스템 아키텍처, 기술 리더십 등을 담당

반응형