728x90

리눅스 시스템의 부팅 과정

 

바이오스 단계

  • PC의 전원 스위치를 켜서 부팅하면 제일 먼저 바이오스(BIOS, basic input/output system)가 동작
  • 바이오스는 PC에 장착된 기본적인 하드웨어(키보드, 디스크 등)의 상태를 확인한 후 부팅 장치를 선택하여 부팅 디스크의 첫 섹터에서 512바이트를 로딩
  • 이 512바이트가 마스터 부트 레코드(master boot record, MBR): 2차 부팅 프로그램(부트 로더)의 위치 저장

 

 

< systemd 서비스 >

init 프로세스와 런레벨 (중요)

 

  • init 프로세스에서 사용하던 런레벨(Run Level)의 개념에 대한 이해 필요
  • init는 시스템의 단계를 일곱 개로 정의하여 구분하고 각 단계에 따라 셸 스크립트를 실행하는데, 이 단계들을 런레벨이라고 함

 

systemd 유닛 (데몬 = 서비스)

  •  systemd는 전체 시스템을 시작하고 관리하는 데 유닛(units)이라 부르는 구성 요소를 사용
  •  systemd는 관리 대상의 이름을 ‘서비스 이름.유닛 종류’의 형태로 관리 
  •  각 유닛은 같은 이름과 종류로 구성된 설정 파일과 동일한 이름을 사용

 

systemd의 기본 개념

systemd는 Centos7부터 본격적으로 기존의init 스크립트를 대체하기 시작

거의 대부분의 서비스가systemd기반 변경

systemd는 init 방식에 비해 가진 장점

  • •소켓 기반으로 동작하여inetd 와 호환성을 유지한다.
  • •셸과 독립적으로 부팅이 가능하다.
  • •마운트 제어가 가능하다.
  • •fsck 제어가 가능하다.
  • •시스템 상태에 대한 스냅숏을 유지한다.
  • •SELinux와 통합이 가능하다.
  • •서비스에 시그널을 전달할 수 있다.
  • •셧다운 전에 사용자 세션의 안전한 종료가 가능하다.

맥북의 경우

https://devlog.jwgo.kr/2019/07/03/how-do-i-check-if-a-service-is-running-in-mac/

 

 

 

728x90

'P-Language > [Linux]' 카테고리의 다른 글

[Linux] 프로세스의 개념  (0) 2022.12.01
[Linux] 특수 접근 권한  (0) 2022.12.01
728x90

프로세스: 현재 시스템에서 실행 중인 프로그램

프로세스의 부모-자식 관계

  • 프로세스는 부모-자식 관계를 가지고 있음
  • 필요에 따라 부모 프로세스(parent process)는 자식 프로세스(child process)를 생성하고, 자식 프로세스는 또 다른 자식 프로세스 생성 가능
  • 부팅할 때 스케줄러가 실행한 프로세스인systemd와 kthreadd프로세스를 제외하면 모든 프로세스는 부모 프로세스를 가지고 있음
  • 자식 프로세스는 할 일이 끝나면 부모 프로세스에 결과를 돌려주고 종료

 

프로세스의 번호 : 각 프로세스는 고유한 번호(PID)

 

프로세스의 종류

  • 데몬 프로세스(HTTP, SSH)
    • 특정 서비스를 제공하기 위해 존재하며 리눅스 커널에 의해 실행
  • 고아 프로세스(systemd - 보통 1번 프로세스)
    • 자식 프로세스가 아직 실행 중인데 부모 프로세스가 먼저 종료된 자식 프로세스는 고아(orphan)프로세스
    • 1번 프로세스가 고아 프로세스의 새로운 부모 프로세스가 되어 고아 프로세스의 작업 종료 지원
  • 좀비 프로세스
    • 자식 프로세스가 실행을 종료했는데도 프로세스 테이블 목록에 남아 있는 경우
    • 좀비 프로세스는 프로세스 목록에defunct프로세스라고 나오기도함
    • 좀비 프로세스가 증가하면 프로세스 테이블의 용량이 부족해서 일반 프로세스가 실행되지 않을 수도 있음

 

SID 

UUID : 장치의 고유번호

 

 

프로세스 목록 보기

현재 실행 중인 프로세스의 목록을 보는 명령: ps

  • 유닉스 (SVR4)옵션 : 묶어서 사용할 수 있고, 붙임표로 시작한다(예 : -ef).
  • BSD 옵션 : 묶어서 사용할 수 있고, 붙임표로 시작하지 않는다(예 : aux).
  • GNU 옵션 : 붙임표 두 개로 시작한다(예 : --pid).

 

포그라운드 작업

  • 포그라운드 프로세스: 사용자가 입력한 명령이 실행되어 결과가 출력될 때까지 기다려야 하는 포그라운드 방식으로 처리되는 프로세스
  • 이를 작업 제어에서는 포그라운드 작업이라고 함
  •  
sleep 100 -> 포그라운드 작업 / sleep 명령이 끝날 때까지 기다려야 한다.

백그라운드 작업

  • 백그라운드 프로세스: 명령을 실행하면 명령의 처리가 끝나는 것과 관계없이 곧바로 프롬프트가 출력되어 사용자가 다른 작업을 계속할 수 있음
  • 작업 제어에서는 백그라운드 작업이라고 함
sleep 100 & -> 백그라운드 작업 
바로프롬프트 나옴			/ 프롬프트가 바로 나와 다른 명령을 실행할 수 있다.

다른 작업하는 동안 그 작업을 연산중 (병렬처리와 비슷)
이전 백그라운드 작업 결과가 언제나올지 모르니 리다이렉트 해주는게 좋음

 

<포그라운드, 백그라운드 프로세스와 작업 제어>

작업 제어

  • 작업 제어는 작업 전환과 작업 일시 중지, 작업 종료를 의미
  • 작업 전환: 포그라운드 작업-> 백그라운드 작업  // 백그라운드 작업->포그라운드 작업으로 전환
  • 작업 일시 중지: 작업을 잠시 중단
  • 작업 종료: 프로세스를 종료하는 것처럼 작업을 종료

 

@ jobs

- 기능 : 백그라운드 작업을 모두 보여줌, 특정 작업 번호를 지정하면 해당 작업의 정보만 보여줌

- 형식 : jobs %작업번호

 

ctrl + c 강제종료 인터럽트

ctrl + d 정상종료

ctrl + z 또는 stop %작업 번호 포그라운드 작업을 일시 중지함

bg %작업 번호 : 백그라운드로 작업시작

fg %작업 번호 : 포그라운드로 작업시작

 

 

작업 예약 

특정한 시간에 작업을 수행하도록 예약할 수 있는 두 가지 방법

  • 정해진 시간에 한 번만 수행 at
  • 정해진 시간에 반복 수행 crontab

at [옵션][시간]

  • - l 실행대기 중 명령의 전체 목록을 출력 (atq 명령과 동일)
  • -r 작업번호
  • -m 메일로알려줌
  • -f 실행할 명령을 파일로 지정

crontab [-u USERID][옵션][파일명]

  •  -e 로그인한 사용자로 예약.
  • -l crontab 파일의 목록을 출력한다.
  • -r crontab 파일을 삭제한다.

728x90

'P-Language > [Linux]' 카테고리의 다른 글

[Linux] 리눅스 시스템의 부팅  (0) 2022.12.01
[Linux] 특수 접근 권한  (0) 2022.12.01
728x90

 

특수 접근 권한

  • 접근 권한은 원래 4자리
  • 생략된 맨 앞자리는 특수 접근 권한 의미
  • 맨 앞자리 숫자가 0이면 일반적인 접근 권한이지만 이 숫자가 1, 2, 4이면 특수 접근 권한이 설정

 

  • SetUID : 맨 앞자리가 4
  • SetGID : 맨 앞자리가 2
  • 스티키 비트(sticky bit) : 맨 앞자리가 1

SetUID : 해당 프로그램을 실행하는 사용자가 프로그램을 실행하는 동안 임시로 파일의 소유자의 권한으로 프로그램을 수행

 

SetGID : 해당 프로그램을 실행하는 사용자가 프로그램을 실행하는 동안 임시로 파일의 소속 그룹의 권한으로 프로그램을 수행

 

777 ->  rwx/rwx/rwx

-> setuid : rws/rwx/rwx (소유자쪽에 s라 표시)

-> setgid : rwx/rws/rwx  (그룹쪽에 s라 표시)

 

특수 접근 권한 왜 필요해?

 

root 계정이 아니라 / 다른 계정일 경우 rwx/- /- 는 실행할 수 없다.

하지만 Setuid rws/-/-  인 경우 임시로 실행가능

 

설정하는 방법

<기호방식> (심볼릭방식)

setuid  : chmod u+s 파일이름

setgid : chmod g+s 파일이름

 

<숫자모드> (8진수방식)

setuid  : chmod 4755 파일이름

setgid : chmod 2755 파일이름

 

setuid/setgid는 보안에 취약하다 파일관리가 필요하다 / 메인관리자가 아닌 일반 

 

 

 

sticky bit(파일에 설정 못함, 디렉토리에만 설정가능) : 해당 특수 권한이 설정된 디렉토리 내에 생성된 파일들은 소유자와 root외 다른 사용자는 삭제하지 못한다.

디렉토리에 쓰기 권한이 있는 경우 디렉토리에서 파일을 만들고 삭제하고 수정할 수 있다.

: 게시판이라 생각하면 쉬움 / A가 쓴글을 B가 못지움

 

setuid 파일 찾기 : find / -perm -4000 

setgid 파일 찾기 : find / -perm -2000

sticky bit 파일 찾기 : find / -perm -1000

setuid and setguid 파일 찾기 : find / \( -perm -4000 -o -perm -2000 \) -ls

 

 

728x90

'P-Language > [Linux]' 카테고리의 다른 글

[Linux] 리눅스 시스템의 부팅  (0) 2022.12.01
[Linux] 프로세스의 개념  (0) 2022.12.01
728x90

< 네트워크란 ? > 

연결하는것

 

LAN (Local Area Network)

 - 근거리 (사무실, 강의실 내)

 - 초기 비용이 높지만, 유지보수 비용 낮음

 - 네트워크 관리자가 관리를 담당

 - 스위치, 허브 등의 장비

 

 

WAN (Wide Area Network)

 - 원거리 (미국 - 한국)

 - 원거리에서 LAN-LAN

 - 초기비용은 낮으나, 지속적 유지비 발생

 - Internet Service Provider 가 관리를 담당 (kt)

 - Router

 

인터넷

 - 전세계 LAN과 WAN이 함께 연결된 거대한 네트워크

 

- 통신방식 

 유니케스트 

  : 서버와 클라이언트간 1:1 통신

 

브로드 캐스트

 :  1 서버 다수의 클라이언트

 

멀티 캐스트

 : 데이터를 전송하려는 특정 그룹에게 데이터를 전송하는 통신 방식

 

 

< IP 주소 (논리적 주소) 변경가능  4바이트>

IPv4 주소 : 주로 이걸 씀

IPv6 차세대 ip 주소

 

물리적 주소 vs 논리적 주소

 

서브넷마스크 - 2진법

네트워크주소 호스트주소 

 

사설 IP 대역대 :

- Class A 규모 : 10.0.0.0 ~ 10.255.255.255 (10.0.0.0/8)

- Class B 규모 : 172.16.0.0 ~ 172.31.255.255 (172.16.0.0/12)

- Class C 규모 : 192.168.0.0 ~ 192.168.255.255 (192.168.0.0/16)

 

공인 ip 대역대 : 인터넷 공인망에서는 ip 대역

사설 ip 대역대 : 사설망 내부에서 쓰는 ip 대역

 

공인 ip와 사설ip를 전환하여 인터넷을 가능케 하는 기술   -> NAT

 

 

게이트웨이 :

- 네트워크의 출입문

- 다른 네트워크라면 게이트웨이 주소로 보내야함

 

< MAC주소 (물리적 주소) : 장치 고유의 주소 > 

 

 ex) 00-05-C5-F0-53-FE (6바이트)

 - 근거리 통신할때는 무조건 MAC주소로 통신 함

 - 기계는 mac 주소를 알아야 통신가능

 - 사람은 ip 주소를 알아야 통신가능

 

ip 주소를 이용해서 mac 을 알아오는 프로토콜 : arp <-> rarp

 

- 근거리 통신을 하기 위해선 mac 주소를 알아야함

- 원거리 통신을 하기 위해선 ip 주소를 알아야함 

 

 

 

 

< DNS : Domain Name Service >

naver.com  = 223.130.195.200

인터넷 주소창에 223.130.195.200 넣으면 네이버로 감

< terminal / cmd >

nslookup  로 dns 확인가능

nslookup naver.com

netstat -a : 사용중인 포트 정보

nslookup : dns 서버 정보

arp -a : arp 캐시 보는 명령어 / arp 테이블

Ctrl + c: 강제종료 (작업하던거 날라감)

C + d : 정상종료

C + z : 일시정지 (가끔 일부명령어로 사용)

Hostname : 네트워크상에서 내컴터 이름

tracert / netstat -r (중요) 라우팅 정보를 알려줌 / 네트워크 경로를 확인 경유지들의 ip를 확인 가능

 

<DHCP service>

우리 컴퓨터의 네트워크를 자동으로 설정해주는 서비스 

 

포트 통신 프로토콜 : TCP / UDP

TCP : 신뢰성있는 통신이 필요 / 상대방과 세션을 연결 

UDP : 간단한 통신이나 빠른 대용량 통신 (동영상 재생) DNS, DHCP / 세션은 맺질 않음

 

 

 

 

 

라우팅테이블 : 통신하기위해선 목적지로 갈수 있는 경로가 적혀있어야 한다.

-> 네트워크 엔지니어, 인프라 엔지니어의 역할

 

매트릭 : 우선순위  윈도우 매트릭 높을수록 우선높은우선 

 

 

 

728x90
728x90

[학습 목표]

가상화 기술 개념

가상화 기술의 종류와 개념

컨테이너 기술에 대한 개념

 

 

<Server virtualizations>

 

Container Technology

- 18년도부터 컨테이너 개념이 들어오기 시작 

앱을 돌릴때 필요한 라이브러리, 어플리케이션 자체를 이미지와해서 만들것을 name space와 cgroup을 통해서 시작하는것을 컨테이너라고 생각하면됨

 

 

도커가 나오면서 컨테이너가 널리 사용됨

특히 구글에서 컨테이너 관리로 썻던 쿠버네티스가 그런 계기가있음

실행에 필요한것들을 이미지에 다 담고 (이미지는 어디든 갈 수 있음) 도커에 넣고 실행하면 컨테이너가 생성

컨테이너 안에 들어가면 로컬에서 쓰던 기분 (어? 쉘인가?)

도커 이미지 : 실행에 필요한것을 다 담음

컨테이너 : 그 이미지를 분리시킨다음 runC 상태로 돌아가서 그 안에 있던 (이미지) 에플리케이션이 독립된 단위로 실행됨

 

 

VM : 은 하이퍼바이져가 들어가 있음  (하이퍼바이저 : 가상화를 해주는 장치 또는 칩)

Container : VM에 필요하던 오버헤드가 없음 

 

 

 

이것만 알아둬라

Container 는 Nacespace/Cgroup의 집합 그럼 나는 어떻게 네트워크를 그 안에서 조절할 것이냐 ? 또는 안에서 조절할 부분 or 밖에서 조절할 부분을 구분할 것인가?

 

 

 

가상화 기술이란

서버, 스토리지, 네트워크 등의 IT 리소스의 물리적인 성질이나 경계를 가리고, 논리적인 리소스

이용 단위로 변환해서 제공하는 기술

 

목적

  • 인프라를 단순화 시킬 수 있다. (사용자 측면)
  • 유휴장비의활용률을높일수있다.(불필요한장비증설방지)
  • 서비스 장애에 대한 신속한 대응이 가능하다.
  • TCO(Total Cost of Ownership)를 절감할 수 있다.
  • 신속한 확장이 가능하다. (Scale Out)

종류

  • 서버가상화
  • 스토리지 가상화
  • 네트워크 가상화

 

 

 

• 가상화의 목적


Isolation from other tenant(세입자 - 여러개의 자원을 하나에서 쓰는 형태)
because basically it’s shared resource.
try to be safe from other noisy neighborhood

 

Application of virtualization technology

분류
설명
애플리케이션 가상화
특징
사용자의 PC에 개별적으로 설치되어 있는 애플리케이션을 가상화를 통해 제공
사용자는 필요한 애플리케이션을 자신의 PC에서 매번 설치하지 않고도 즉시 사용 가능
역할
클라우드의 SaaS(Software as a Service) 구현의 기반 기술 제공
데스크톱 가상화
특징
서버 측 데스크톱 가상화는 사용자의 데스크톱에서 Windows Vista, Windows 7 등의 이기종의 또 다 른 데스크톱을 가상으로 소유가 가능하게 함
클라이언트 측 데스크톱 가상화는 PC 안의 이기종의 가상 데스크톱을 운영 가능 하도록 함 데스크톱 가상화를 통한 개인 작업 공간과 회사 작업 공간의 분리가 가능해 짐
역할
클라우드의 DaaS(Desktop as a Service) 구현의 기반 기술 제공
서버 가상화
특징
데이터센터 내의 수십 대의 물리적인 서버 워크로드들을 몇 대의 가상 서버로 통합 집적 (Consolidation)하여 물리적인 상면 비용, 관리적인 측면의 비용, Green IT 측면의 전력량을 포함한 서버 자원 활용도를 증대시킬 수 있음
역할
클라우드의 IaaS(Infrastructure as a Service) 구현의 기반 기술 제공
스토리지 가상화
특징
필요로 하는 스토리지 공간 대신 Thin-Provisioning이라는 기술을 통해 최소 공간만을 가상으로 할당 하여 서비스 구현이 가능하도록 함
이기종의 스토리지 시스템 통합에 사용할 수 있는 환경을 제공
역할
클라우드의 IaaS(Infrastructure as a Service) 구현의 기반 기술 제공
네트워크 가상화
특징
하드웨어 어플라이언스 형태로 존재해 왔던 L2, L3, L7 스위치, 네트워크 방화벽, 보안 장비들을 가상 머신으로 구현하고, 네트위킹 자원들이 하나의 공유된 물리적인 환경에서도 내부적으로는 가상화를 통해 분리되어 동작하게 함
역할
멀티 테넌시(Multi-Tenancy)를 갖춘 IaaS 구현의 기반 기술 제공

 

 

서버가상화

시스템 자원을 공유(pool & share)함으로써 전체적인 시스템의 활용도를 증대시킬 수 있고, 자동화 기술과 함께 적용함으로써 시스템 사용자의 서비스 수준을 보다 향상시켜 줄 수 있다.

하이퍼바이저 : 가상화를 해주는 장치 또는 칩

 


<서버 가상화 기술>

 

하이퍼바이저(Hypervisor)

  • 프로세서나 메모리와 같은 다양한 컴퓨터 자원에 서로 다른 각종 운영 체제(OS)의 접근 방법을 통제하는 얇은 계층의 소프트웨어
  • 다수의 OS를 하나의 컴퓨터 시스템에서 가동할 수 있게 하는 소프트웨어로 중앙 처리 장치(CPU)OS 사이에 일종의 미들웨어로사용 됨
  • 하나의 컴퓨터에서 서로 다른OS를 사용하는 가상 컴퓨터를 만들 수 있는 효과적인 가상화엔진
Bare-Metal(native) Hypervisor
Hosted Hypervisor
  • Host OS가 필요없다.
  • Host OS가 없어 오버헤드가 적다.
  • 각 VM별 관리가 유연하다.
  • 자체적인 관리 기능이 없어 별도의 관리 솔루션이 필요하다.
  • Host OS가 필요하다.(리눅스, 윈도우 등)
  • Host OS 상에 가상 머신을 배치하므로 오버헤드
  • 가 발생한다.
  • VM 생성이 간단하다.
  • 다양한 관리 솔루션이 있다.

 

 

 

호스트 OS 가상화 vs 하이퍼바이저 가상화

 

 

 

가상화유형

 전 가상화 (full-virtualization)

시스템 전체를 완전히 가상화 하여 시스템의 Bios부터 CPU, Memory, I/O 등을 완전히 에뮬레이션 하여 가상화 하는 방법

장점
단점
하드웨어를 완전히 가상화 하기 때문에 Guest OS에 아무런 수정없이 Windows, Linux까지 다양 한 OS를 이용할 수 있다.
가상머신의 유지보수가 쉽다.
전 가상화를 실현하기 위해 CPU의 VT(Virtualization Technology)를 이용하므로 성 능의 저하가 발생한다는 단점이 있다.

 

 

– 반 가상화 (para-virtualization)

하드웨어 전체를 가상화 하는 대신에 가상화가 적용된 리눅스 커널을 시스템 부팅 시 적용하는 것으로 모든 장치를 가상화 하는 것은 아님

 

장점
단점
가상머신이 직접 하드웨어를 제어하는 것이 아니 라 하이퍼바이저에게 의뢰, 하이퍼바이저가 제어 를 하기에 높은 성능을 유지할 수 있다.
반 가상화를 실현하기 위해서는 가상머신 OS의 커널 일부분을 수정해야 한다.
가상머신 유지보수가 어렵다. (가상머신 비밀번 호 분실 시 복구 불가능)

 

요즘에는 반가상화 전가상화 사이에 차이가 크게 사라짐 

 

KVM

  • –  Kernel-based Virtual Machine의 약자
  • –  http://www.linux-kvm.org
  • –  오픈 소스 소프트웨어
  • –  x86 서버 기반의 전 가상화 솔루션 (Using Intel VT or AMD-V)
  • –  게스트 운영체제의 수정이 필요 없음
  • –  Using QEMU
    • QEMU 는 가상화 에뮬레이터
    • 게스트 OSI/OQEMU를 통해 제공한다.
  • –  VM이 새로운 프로세스와 QEMU 프로세스를 이용하여 실행된다는 단점이 있음 (오버헤드 발생)
  • –  ESX Server, Xen Server 등과 같이 전용 하이퍼바이저가 아닌 Linux 자체를 호스트 OS로 이용
  • –  RHEV (RedHat Enterprise Virtualization) 솔루션의 기반

KVM 아키텍처

 

 

Xen

서버 가상화 기술

  • –  캠브리지 대학교의 연구 프로젝트로 개발
  • –  http://www.xen.org
  • –  오픈 소스 소프트웨어
  • –  x86 서버 기반의 반 가상화 솔루션 (Paravirtualizing VMM-Virtual Machine Monitor)
  • –  게스트 운영체제의 수정이 필요함
  • –  전 가상화에 비해 처리에 대한 오버헤드가 적다.

하드웨어 기술(Intel VT or AMD-V)이 발전함에 따라 성능 차이가 줄어들고 있음

  • –  x86 서버 기반의 전 가상화 솔루션(Intel VT or AMD-V)에서는 HVM(Hardware Virtual Machine)을 구현할 수 있다.
    • 반가상화/전가상화모두구현가능
  • –  Citrix Xen Server 솔루션의 기반

Xen 아키텍처

728x90

'Network > [Cloud]' 카테고리의 다른 글

[Cloud] Telemetry  (1) 2022.12.10
[Cloud] 도커 기본 명령어  (0) 2022.12.05
[Cloud] 도커란?  (0) 2022.12.05
[Cloud] 1. 클라우드 컴퓨팅이란?  (0) 2022.11.25
728x90

[학습 목표]

Cloud Computing 개념

서비스와 마이크로 서비스의 개념과 차이점

IaaS, PaaS, Saas 특징

 

 

 

 

초록색이 많을 수 록 돈이 많이 듬 -> 그래서 최대한 돈을 아낄려고 하이브리드 형태로 사용

 

# On-Premises / (레거시) 물리적 - 가상화 안됨

- 규모가 있는 기업에서 사용하는 방식

- 자체적으로 데이터센터와 서버실 구축하여 운영

 

# 퍼블릭 클라우드 (AWS) / 클라우드 (가상화)

- 초기투자 필요없음

- 인터넷을 통해 불특정 다수에게 돈주고 빌려줌

 

# 프라이빗 클라우드 

-특정 대상을 지정해서 서비스를 제공하는 클라우드 서비스

- 단일 기업, 계열사 등에만 지원

 

 

AWS와 같은 Cloud Service Provider 업체에서는 다음과 같은 서비스 유형을 제공함

 

# IaaS

- Infrastructure as a Service

- Server, OS, Network, Storage 등을 제공

- 필요로 하는 자원의 규모와 성능 등에 의해 비용 발생

 

# PaaS

- Platform as a Service

- 소프트웨어 개발 및 운영 환경을 제공

- 인프라에 대한 관리 부담을 질여 개발에 집중하도록 함

 

# SaaS

- Software as a Service

- 클라우드 벤더가 제공하는 시스템 및 스프트웨어를 직접 사용 (한컴 독스)

- 인프라, 소프트웨어 구축 시간이 없거나 매우 짧음

 

클라우드 서비스가 좋은 이유

# 초기 투자 없음 

  장비를 빌려쓰기 때문에 장비 구매, 설치 불 필요

 

# 트래픽 변동이 가능

  요구량에 조절이 가능해서 트래픽 예측이 힘들때 좋음 

 

# 복구가 빠름

  무 중단 또는 재해 복구가 빠름

  이중화, 백업 구성이 가능

 

# 빅데이터 처리에 유용

   많은 데이터를 직접 가지고 있을 필요없음

 

# 웹/모바일앱 등 백엔드로 이용가능

  백엔드를 클라우드를 이용하여 구축가능

  

 

 

 

 

서비스란 결국 웹, 어플리케이션, 디비 서버를 연결해서 사용자가 사용할 수 있게 해주는걸 의미함

 

 

[Micro Service?]

쉽게 말해 점점 작게 세분화

 

 

-

 

클라우드 컴퓨팅이 뭐냐?

: 어떤 서비스를 해준다? -> 클라우드다

 

 

IT service 보다는 Product 라는 말이 맞음

-> 하나의 제품으로 보는게 맞다 : 제품은 어떤 목적성을 띔, 필요한 니즈를 채움

 

Engineering?

일정 생산 목적에 따라 유기적인 체계로 구성하는 활동  -> 클라우드 제품을 설명하기 위해 필요한 개념

 

Technology?

way of saving cost or creating product -> 기술과 이윤!

 

----------------------------------------------------------------------------------------------------------------------

 

 

 

 

 

[클라우드 컴퓨팅]

유틸리티 컴퓨팅 아키텍처의 새로운 패러다임

소수의 컴퓨팅 자원을 다수의 컴퓨팅 자원처럼 사용

사용자 중심의 아키텍처

클라우드 컴퓨팅 아키텍처는 그리드 컴퓨팅 기반(유틸리티 컴퓨팅과의 차이점)

 

[그리드 컴퓨팅]

분산 컴퓨팅 아키텍처의 하나

다수의 컴퓨팅 자원을 하나의 컴퓨팅 자원처럼 사용

컴퓨팅 중심의 아키텍처

분산 파일 시스템/ 스토리지는 오히려 그리드 컴퓨팅 아키텍처

그리드 컴퓨팅 아키텔처는 서비스 아키텍처가 아님

표준화에 실패 -> 클라우드 컴퓨팅에 뺏김

 

 

 

- 사용하고 있는 서비스는 열어보면 이렇게 다양한 분산 시스템을 필요로 함 (내부에 있음) 

 

 

 

 

아키텍처 개념 클라우드 컴퓨팅과의 비교
Grid Computing 많은 IT 자원을 필요로 하는 작업을 위해 인터넷 상의 분산된 다양한 자원을 공유해 가상의 슈퍼컴퓨터처럼 활용하는 방식 그리드 컴퓨팅이 인터넷 상의 모든 컴퓨팅 자원을 통합해 사용하는데 반해,

클라우드 컴퓨팅은 서비스 제공 사업자의 사유 서버 네트워크를 빌려서 활용

Utility Computing
서버, 스토리지 등 컴퓨팅 자원을 보유하지 않은 채 가스나 전기처럼 사용량에 따라 과금되는 방식 클라우드 컴퓨팅의 과금 방식과 동일
SBC :
Server Based Computing
서버에 응용 소프트웨어와 데이터를 저장해 두고 필요할 때마다 접속해서 쓰는 방식으로 모든 작업을 서버가 처리 클라우드 컴퓨팅은 서비스 제공자의 가상화된 서버를 이용하고, SBC는 특정 기업내 서버를 활용한다는 차원에서 구분되나, 서버 기반의 컴퓨팅이 발전하면서 그 구반이 모호해 짐
Network Computing 서버 기반의 컴퓨팅처럼 응용 소프트 웨어를 서버에 두지만, 작동은 이용자 컴퓨터의 자원을 이용해 수행하는 방식 클라우드 컴퓨팅은 이용자 컴퓨터가 아니라 클라우드 상의 IT 자원을 이용하는 방식

 

 

 

AWS가 처음 나올때 아마존에서 장비 사용율을 보니 5%로도 안됨 그래서 서버를 빌려주기 시작하면서 나옴

 

 

 

[클라우드 컴퓨팅이란?]

- Cloud Computing as Utility Computing 

@유틸리티 컴퓨팅에서 유래

@ 기본 운영방식

   - 가상화로 구성되어 있다. <서버 가상화, 스토리지 가상화>

  -  전기 사용요금과 같이 사용한 만큼 요금을 내라 

 

@ HP, IBM, SUN 등 하드웨어 제조 회사가 유틸리티 컴퓨팅 주도 / 반면 클라우드 컴퓨팅은 AMS,Google, MS 클라우드 밴더라고 부름

@ IaaS 중심의 클라우드 컴퓨팅

  - 미래에는 경쟁력이 없다 (가격으로 승부하기 때문)

  - 한국적인 클라우드 컴퓨팅은 없다

  - 보안 문제와 응답 시간만 같다면 누구나 값 싼 서비스를 선택하게 된다.

@ 항상 Global Computation을 생각하자

 

 

--Only Cloud Computing

@ 기업에서 사용하는 컴퓨팅 자원을 표준화 해 그 자원을 가상 환경으로 제공하는 방식

@ Iaas,Paas, SaaS가 기본임

@ 원가가 저렴해야 한다

 - 밴더에 독립적이어야 한다

 - 표준화가 되어 있어야 한다

@ 자동화가 되어 있어야 함

 

---Cloud Computing is.

@ IT as a Service 

 -Infrastructure as a Service 

 - Platform as a Service

 - Software as a Service

 

@ Cloud Computing is not virtualization.

@ Dynamic set of Connected Computers

 - Computers are PC, Server, Mainframe, Sensor, Phone...

 - Connect is a internet environment

 - Dynamic is on-demand or at runtime or near real-time

 - Set is cluster. is not grid

 

@ have to be automated and stardized (자동화 및 표준화!!)

 

 

 

대표적 회사 / MS는 다 가지고 있음

 

 

 

 

728x90

'Network > [Cloud]' 카테고리의 다른 글

[Cloud] Telemetry  (1) 2022.12.10
[Cloud] 도커 기본 명령어  (0) 2022.12.05
[Cloud] 도커란?  (0) 2022.12.05
[Cloud] 2. 클라우드 서버 가상화 (Server virtualizations)  (1) 2022.11.26
728x90

미안합니다 SI 개발자 형님들.. 형님들은 죄가 없겠지요
PM님들... SI개발자님들 고객사가 이렇게 요구한다면 제발 사전에 말좀해주세요.. 이거 UX 구린거알잖아요!

 

1. 주소 검색을 위해 시 구 입력해야할때

--시 --구/동 하나씩 다 입력해야 할 때.

SI 웹 개발자 가는 주소를 카카오 주소 api로 할 수 있게 통일해 주시지요... 

https://postcode.map.daum.net/guide

 

 

2. 번호 입력창 구분되어 있을 때

010 1234 5678 입력했는데

010 1234 // ---- 입력이 안되어있어서 마우스 한번 더 눌러야하는 그 기분... 음 나만 예민한가?

 

 

3. 인증번호 입력 중 페이지 리프레쉬....

부모님 가끔씩 인증번호 놓치는 경우 있는데

문자메시지함 들어갔다가 번호 외우고 웹페이지 다시 들어왔는데 페이지 리프레쉬되는 경우 허다함

 

3-1. 인터넷등기소 같은경우 

열심히 작성칸 다 채우고 결제창 눌렀는데 

결제를 위한 보안프로그램 설치하라고 갑자기 리다이렉트 됨 물론 작성내용 다 사라짐 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 

 

4. 유효성/자격 검사는 미리 좀 하고, 결과를 알려주면 안됩니꺼?

 기껏 신청서 입력 다 했는데 

 유효성/자격이 안된다고 그제야 알려주다니..

예시 농협 콕뱅크 (농협, 수협 , 정부 어플 - 노답)
본인인증 다 끝내고 - 관련 정보 다적고 신청서 보내니 - 유심관리앱 깔아라?
애초에 유심관리앱을 깔게 유도하면 되잖아? 이게 어려워?


5. 동의서 팩스로 보내야 할 때

심지어 hwp파일만 올려둔 경우

클라우드 서비스로 해주면 정말 감사하겠습니다. 과학창의재단을 이렇게 하던데 감동 받음!

 

6. 색에 무관하게 알 수 있게 좀..

https://www.youtube.com/watch?v=VkKda38UDJ0

 



5. 은근히 선택옵션 광고 끼워넣기
필수, 선택 약관에 
필수만 선택 옵션을 좀 넣어주세요

728x90

'글적글적 > 바꿔야할부분' 카테고리의 다른 글

저출산대책  (0) 2024.06.07
팩스를 도대체 왜 아직까지 쓰는건가?  (0) 2023.02.13
728x90

Network Attached Storage

말 그대로 네트워크에 연결된 저장장치이다

다시 말해 집에 있는 저장장치가 인터넷만 연결되어있으면 어디서나 언제나 내 PC와 연결된 것 같은효과!

 

그래서 뭐?

 

우선 나의 NAS  용도를 적어본다

 

- 미디어 저장 (usb or SD 카드만 꽂으면 알아서 백업) - 이 기능 있는 외장하드 찾을려고 진짜 개고생했는데 (Mypassport sdcard) -  1TB짜리가 무려 40만원!! 나스는 공짜.... 

- 미디어 원격저장(FTP 통신으로 카메라 사진/영상을 인터넷만 있으면 바로 나스 폴더에(지정한 디렉토리)에 바로 꽂아줌)

- 미디어 다운로드 (인터넷만 연결되어있으면 어디서든 다운로드 가능) + 영상컷편집기(루마퓨전)에서 나스에 있는 영상 바로 찾아줌!!

- 미디어 재상 (nPlayer등 어플로 나스에 연결하면 끝 - iCloud 및 패드 용량아끼기) 

- Mediaserver - 집 TV or 빔프 에서 외장하드 연결없이 바로 재생 (칼세이건 코스모스 몰아보기 최고)

- DB 연결 - Docker container (Oracle) 또는 Maria DB 생성 가능 - 

- webstation - 웹연결 - 웹개발하시는분들 포폴용으로 추천

- Mac Timemachine - Mac 백업용

- MailStation - 메일 막힌곳에서 메일보내기 가능 (+ 파일 바로첨부 가능 / 학교에서 일 할때 진짜 애용하던 기능)

- Surveillance Station - 알리발 2만원짜리 cctv를 20만원짜리로 만들어줌 (시놀로지는 ONVIF 2개나 공짜로 붙일 수 있음)

- HomeAssistant - IOT 끝판왕!!  그냥 막 입문 ->  zigbee 허브(ST) -> HA서버로 한번에 관리

(자동 루틴 한번 맛보면 절대 못 빠져나감) 문열고 나가면 알아서 엘레베이터 잡아줌... 요즘 프리미엄아파트 이거 장사하던데
- N8N - Ai agent 로 가장 널리쓰임 나스가 있으면  자체호스팅한다면 서버비없이 무제한이용가능! 

 

 

 

영상찍는걸 좋아하다보니 4k 60p 으로 찍으면 하루에 100GB씩 막 나오니 기존 물리적 외장하드로는 관리가 너무 힘들었다

처음엔 그냥 네이버/애플/ 구글드라이브 정액제 끊을까 하다가 2년정도 따져봤을때 나스사는게 이득인 것 같아서

시놀로지 나스로 입문했는데 진짜 신세계를 경험했다. 처음 세팅할때 아무것도 몰라서 유튜브 구글 뒤져가면서 포트포워딩이 뭔지 smb, webDav, https 등 하나씩 알아가는 재미도 함께 느낄 수 있다... 알고보니 다 상식인 내용들인데 덕분에 알게됐지

 

개인적으로 네이버/ 구글드라이브/ 애플 icloud에 매달 돈 주느니 (필자도 g-suit, icloud 유료고객이였음)

개인용 서버 구축이 돈도 아끼고 훨씬 커스터마이징 하기 좋다!

 

기회가 된다면 NAS 편으로 내가 아는 미천한 지식으로 나의 세팅과정을 천천히 올려봐야겠다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90
728x90

https://limkydev.tistory.com/168

728x90
728x90

# 데이터 정제, 분석, 시각화
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import font_manager, rc     # 한글깨짐 방지 처리 위한 모듈 임포트

# matplotlib 한글깨짐 방지
font_path = r"C:\Users\tjoeun\AppData\Local\Microsoft\Windows\Fonts\D2Coding-Ver1.3.2-20180524-all.ttc"
font = font_manager.FontProperties(fname=font_path).get_name()
rc('font', family=font)


data = pd.read_csv('도로교통공단_시도시군구별교통사고통계.csv')
# print(data.head(10))

# 서울에서 사고건수가 많은 데이터순
data_acc = data[ data['시도'] == '서울'].sort_values(by='사고건수', ascending=False)
# print(data_acc[['시도', '시군구', '사고건수']])
# print(data_acc.shape)

# 서울시 시군구별 교통사고 발생 top 10
# print(data_acc[['시도', '시군구', '사고건수']][:10])
# plt.figure(figsize=(10, 6))     # 사이즈 지정
# plt.title('서울시 시군구별 교통사고 발생 top 10')       # 제목 붙히기
# plt.bar(range(10), data_acc['사고건수'][:10])       #막대 그래프 (x, y)
# plt.xticks(range(10), data_acc['시군구'][:10])     # x축 단위 라벨 (x, 라벨값)
# plt.show()

# 전국 시도별 사고건수/사망자수 top 10
# 시도로 그룹
# print(data.groupby(by='시도'))
# print(data.groupby(by='시도').count()) # 시도별 구의 개수
# print(data.groupby(by='시도').sum())  # 그룹별 합계 (시도별 합계)
data_grby_city = data.groupby(by='시도', as_index=False).sum() # 그룹핑 기준인 시도를 인덱스로 사용 안하겠다 지정
print(data_grby_city.shape)
print(data_grby_city.sort_values(by='사고건수', ascending=False))
print(data_grby_city.sort_values(by='사망자수', ascending=False))
data_grby_city_sorted_acc = data_grby_city.sort_values(by='사고건수', ascending=False)
data_grby_city_sorted_death = data_grby_city.sort_values(by='사망자수', ascending=False)

print(data_grby_city_sorted_acc['시도'])
print(data_grby_city_sorted_acc['사고건수'])

#  그래프 그리기 : 사고건수 top10
# plt.figure(figsize=(10, 6))     # 사이즈 지정
# plt.title('전국 시도별 교통 사고 발생 top 10')       # 제목 붙히기
# plt.bar(range(10), data_grby_city_sorted_acc['사고건수'][:10])       #막대 그래프 (x, y)
# plt.xticks(range(10), data_grby_city_sorted_acc['시도'][:10])     # x축 단위 라벨 (x, 라벨값)
# plt.savefig('전국시도별교통사고발생top10.png')
# plt.show()
#  막대그래프 그리기 : 사망자수 top10
# plt.figure(figsize=(10, 6))     # 사이즈 지정
# plt.title('전국 시도별 교통 사고 사망자수 top 10')       # 제목 붙히기
# plt.bar(range(10), data_grby_city_sorted_death['사망자수'][:10])       #막대 그래프 (x, y)
# plt.xticks(range(10), data_grby_city_sorted_death['시도'][:10])     # x축 단위 라벨 (x, 라벨값)
# plt.savefig('전국시도별교통사고사망자수top10.png')
# plt.show()
#  파이그래프 그리기 : 사망자수 top10
# colors = ['red', 'yellow', 'purple', 'burlywood', 'lightcoral']
# plt.title('전국 시도별 교통 사고 사망자수 top 10')
# plt.pie( data_grby_city_sorted_death['사망자수'][:10],
#         labels=data_grby_city_sorted_death['시도'][:10],
#         startangle=90,
#         counterclock=False,
#          autopct='%.1f%%',
#          colors=colors)
# plt.savefig('전국시도별교통사고사망자수top10.png')
# plt.show()

# 지도에 그리기
'''
- 라이브러리 : folium 
- 지도 데이터 파일 : .geojson 
    공간정보시스템연구소 : http://www.gisdeveloper.co.kr/?p=2332
    
    지도 원천데이터는 SHP(Shape file) 이 필요 
    SHP파일은 직접핸들링하기 힘드러 GeoJSON이라는 지리정보표시를 위한 표준 JSON 포맷으로 변환 
    https://mapshaper.org/ : 해당 사이트에서 다운받은 지도 파일 4개 넣고 단순화시켜 변환가능 
    1. 맵쉐이퍼사이트에서 select 버튼을 누르고, 다운받아 압축해제한 4개 파일 선택 
    2. 팝업에 nap-verticles 체크, input란에 'encoding=euc-kr' 입력하고, import 누르기 
    3. 지도위 오른쪽 상단에 simplyfy 버튼 누르고, 팝업옵션에 apply 누르고
    4. 상단 가운데에 settings 프로그래스바 움직여서 단순화 시키고 
    5. 오른쪽 상단에 export 누르고, GeoJson 선택하고 export하면 다운받아짐. 
    
    * folium * 
    시각화 패키지 중 하나로 지도를 그려주는 모듈. 경량. 
    
'''
import json
import folium

# 전국 시도별 교통사고 지도 그래프
print(data[['시도', '사고건수']].groupby(by='시도').sum())
data_grby_city2 = data[['시도', '사고건수']].groupby(by='시도').sum()

json = json.load(open("TL_SCCO_CTPRVN_min.json", encoding="utf-8"))
# print(json['features'][0]['id'])
print(data_grby_city2['사고건수'].index[0])
for i in range(17):
    # 'id' : 사고건수값
    json['features'][i]['id'] = data_grby_city2['사고건수'].index[i]

# map 객체 생성 : 대한민국 중심좌표를 센터로, 줌 레벨 7로 시작하는 맵 생성
map = folium.Map(location=[36.2002, 127.054], zoom_start=7)
# Choropleth : 지도위에 띄워줄 그래프 레이어, 설정하여 맵에 추가
folium.Choropleth(
    geo_data=json,
    name='choropleth',
    data=data_grby_city2['사고건수'],
    key_on='feature.id',
    fill_color='YlGnBu',
    fill_opacity=0.8,
    line_opacity=0.2).add_to(map)

# 레이어 컨트롤러러에 지도 추가
folium.LayerControl().add_to(map)
map.save('trafficMapResult.html') # 저장

# 대한민국 중심좌표 : 36.2002, 127.054
# 서울 중심좌표 : 37.541, 126.986




















728x90
728x90

1.  실행되는 순서가 다르다. / 관리되는 컨테이너가 다르다 ( Filter -> web container / Interceptor -> Spring container)

  why?

  filter는 자바에서 제공하는 

 interceptor는 스프링에서 제공 -> DispatcherServlet에 의해 호출됨 -> HttpServletRequest, HttpServletResponse 객체를 변경할 수 없다! ( filter는 가능)

 

 

 

2. 어댑터 또는 데코레이터 패턴 적용여부

Filter O

   -> filter의 경우 디스펫치서블렛 불리기 이전이므로 /

서블릿 리퀘스트를 요청받아 -> HTTP서블릿 리퀘스트 -> filter -> chain.doFilter

doFilter 에서 요청(Request)/ 응답(Response) 변경할 수 있음

 

-> Filter에서 선택적으로 요청, 응답 객체를 사용자 정의 구현체로 래핍하여 어댑터(래퍼), 또는 데코레이터 패턴으로 적용가능

 

Interceptor X

 

래퍼 없을땐 1번만 적용됨
래퍼 재정의 해서 반복가능

3. 이러한 이유로

Filter 

< 스프링과 무관하게 전역적으로 처리해야하는 작업, 웹 어플리케이션에 전반적으로 사용되는 기능>

@ 공통된 보안 및 인증

   - 전역적으로 해야하는 보안 검사 (XSS,CSRF 방어 등)

@ 모든 요청에 대한 로깅 또는 감사 (위험 관리)

@ 이미지/ 데이터 압축 및 문자열 인코딩

@ Spring과 분리하려는 모든 기능

 

대표적으로 SpringSecurity가 Filter 기반의 인증 및 인가를 검사 할 수 있다. 따라서 Spring MVC에 종속적이지 않다

 

Interceptor

<클라이언트 요청과 관련되어 전역적으로 처리해야하는 작업>

@ 세부적인 보안 및 인증

  - 클라이언트 요청과 관련된 인증, 인가 작업.

 특정 그룹의 사용자에 대한 기능 제한 등

@API 호출에 대한 로깅 또는 감사

@Controller로 전달되는 정보의 가공

 

 

https://www.youtube.com/watch?v=nQizVrBYCO0&t=559s

728x90

'WEB Creator > [Spring]' 카테고리의 다른 글

[Spring] @Controller와 @RestController  (0) 2022.08.31
[Spring] File Download  (0) 2022.08.25
[Spring] File Upload  (0) 2022.08.25

728x90

2. 파일 다운로드


1) 우선순위 지정
2) DownloadView.java 기능 사용을 위해 bean으로 등록
3) jsp 페이지에 다운로드용 버튼 하나 만들고 요청경로 지정
4) Controller에서 해당 요청 처리 매핑메서드 만들어 DownloadView의 기능 호출

 

2-1 우선순위 지정

AppServlet > Servlet-context 에 들어가서 해당 코드 입력하기

 

	<!--  InternalResourceViewResolver 보다 우선순위를 높게해서 먼저 다운로드에 관하는
    				beannameViewResolve 실행되게끔 -->
	<beans:bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
		<beans:property name="order" value="0"></beans:property>
	</beans:bean>

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
		<beans:property name="order" value="1"></beans:property>
	</beans:bean>

 

 

2-2 Downloadview 기능을 위한 bean등록

 

 

AppServlet > root-context 에 들어가서 해당 코드 입력

<bean id="fileDown" class="com.upload.util.DownloadView" />

 

src/main/java > com.upload.util 패키지 생성후

해당 java 클래스 만들기

 

package com.upload.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.util.FileCopyUtils;
import org.springframework.web.servlet.view.AbstractView;

public class DownloadView extends AbstractView {
	
	public DownloadView() {
		setContentType("application/download; charset=utf-8"); 
	}
	@Override							
	protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
			HttpServletResponse response) throws Exception {		

		File file = (File)model.get("downloadFile");		
		response.setContentType(getContentType()); 			
		response.setContentLength((int)file.length());		
		
		String fileName = java.net.URLEncoder.encode(file.getName(), "UTF-8"); 
		response.setHeader("Content-Disposition", "attachment;filename=\""+fileName+"\";");  
		response.setHeader("Content-Transfer-Encoding", "binary");
		
		OutputStream out = response.getOutputStream();		
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(file);		
			FileCopyUtils.copy(fis, out);			
		}catch (Exception e) {
			e.printStackTrace();
		}finally {
			if(fis != null) { try {fis.close();}catch(Exception e2) { e2.printStackTrace(); } }
			out.flush();
		}
	}
}

 

 

2-3 jps 페이지에 다운로드용 버튼 만들고 요청경로 지정

 

helloDown.jsp

window.location='/upload/download  요청경로지정

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Insert title here</title>
</head>
<body>
	<h2> hello down page</h2>
	<h3> 다운을 받고 싶으면 아래 버튼을 누르세요 !!!</h3>
	<button onclick="window.location='/upload/download'"> 다운로드  </button>
</body>
</html>

 

 

 

 

2-4  Controller에서 해당 요청 처리 매핑메서드 만들어 DownloadView의 기능 호출

 

	// 다운로드 버튼 띄운 화면	
	@GetMapping("helloDown")
	public void helloDown() {
		
	}

	// 다운 요청 처리
	@GetMapping("download")
	public ModelAndView down() {
		// 다운 시킬 파일 준비
		File f = new File("C:\\img\\ham.jpg");
		// 생성자 매개변수
		// String viewName 		:	view 이름 -> xml 지정한 downloadView 빈의 id값
		// String modelName		:	파라미터명 지정 (이름) 
		// Object modelObject	:	데이터 (다운 시킬 파일)
		ModelAndView mv = new ModelAndView("fileDown", "downloadFile", f);  //root에 bean으로 fileDown 만듦 그 다음 dowloadFile 키와 f라는 value를 줌 
		return mv;
	}
}
728x90

'WEB Creator > [Spring]' 카테고리의 다른 글

[Spring] Filter와 Interceptor의 차이점  (0) 2022.09.08
[Spring] @Controller와 @RestController  (0) 2022.08.31
[Spring] File Upload  (0) 2022.08.25
728x90

spring mvc 에서 파일 업로드 다운로드 하는 방법!

 

 

1. 파일 업로드

 

1-1 라이브러리 추가 (pom.xml에 추가)

commons-fileupload, commons-io.jar 추가하기 

 

		<!-- 파일업로드용 라이브러리 2개 추가 -->
		<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
		<dependency>
		    <groupId>commons-fileupload</groupId>
		    <artifactId>commons-fileupload</artifactId>
		    <version>1.4</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
		<dependency>
		    <groupId>commons-io</groupId>
		    <artifactId>commons-io</artifactId>
		    <version>2.6</version>
		</dependency>

1-2 MultipartResolver 추가 (root-context.xml)

	<!--  파일 업로드 -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="-1"></property>  <!-- '-1' 은 파일크기 무제한 -->
		<property name="defaultEncoding" value="UTF-8"></property>
	</bean>

 

 

1-3 파일 업로드 view(jsp) 작업 

 

간단하게 파일 uploadForm과  uploadPro 만들고

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>uploadform</title>
</head>
<body>

	<h2> File Upload</h2>  //post!! multipart 로 보내기!!
	<form action="/upload/uploadPro" method="post" enctype="multipart/form-data">
		message : <input type="text" name="msg" /> <br/>
		file 	: <input type="file" name="img" /> <br/>
		message : <input type="submit" value="전송" /> <br/>
	</form>

</body>
</html>



-------------------------------------------------------------------------------
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>upload Pro</title>
</head>
<body>

</body>
</html>

 

 

 

1-4 파일 업로드 컨트롤러 작업 

 

 파일업로드 작업
MultipartHttpServletRequest 인터페이스

* 주요 메서드
Iterator<String>  getFileNames() : 업로드된 파일들의 파라미터 명 리턴
MultipartFile getFile(String name) : 파라미터명이 name인 파일 리턴
List<MultipartFile> getFiles(String name) : 파라미터명이 name인 업로드 파일 정보 목록 리턴

* 작업 순서
- 처리 매핑 메서드에 매개변수 MultipartHttpServletRequest 지정
- request에서 파일 정보 꺼내담기
- 파일 저장 경로 + 새파일명 만들어 File 객체 만들기 (파일 이름 중복 안되게)
- .transferTo() 메서드로 파일 저장

package com.board.controller;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import lombok.extern.log4j.Log4j;

@Controller
@RequestMapping("/upload/*")
@Log4j
public class UploadController {
	
	@GetMapping("uploadForm")
	public void upload() {
		log.info("upload form!!!!!!!!!!!!!!");
	}
	
	@PostMapping("uploadPro")
	public void uploadPro(String msg, MultipartHttpServletRequest request) { // msg(text), img(file) 
		log.info("*********upload pro*************");
		log.info("********* msg : " + msg );
		//log.info("********* img content type : " + request.getContentType());
		//log.info("********* img : " + request.getFile("img")); // 파일 정보 꺼내기
		
		try {
			// 전송한 파일 정보 꺼내기
			MultipartFile mf = request.getFile("img");
			log.info("****************** original file name : " + mf.getOriginalFilename());
			log.info("****************** file size : " + mf.getSize());
			log.info("****************** file contentType: " + mf.getContentType());
			
			
			// 파일 저장 경로
			String path = request.getRealPath("/resources/save");
			log.info(" save path : "+ path);
			// 새파일명 생성
			String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();  // 하이픈 다 빼버림 대문자로
			log.info("***********uuid : " + uuid);
			// 업로드한 파일 확장자만 가져오기 
			String orgName= mf.getOriginalFilename();
			// beach.jpg   -> .jpg만 두고 나머지는 지움
			String ext = orgName.substring(orgName.lastIndexOf("."));
			
			// 저장할 파일명
			String newFileName = uuid + ext;
			log.info("*****new fileName : " + newFileName);
			
			//저장할 파일 전체 경로
			String imgPath = path + "\\" + newFileName;
			log.info("****imgPath : " + imgPath);
			
			
			// 파일저장
			File copyFile = new File(imgPath);
			mf.transferTo(copyFile);
			
		}catch(IOException e){
			e.printStackTrace();
		}
	}
}
728x90

'WEB Creator > [Spring]' 카테고리의 다른 글

[Spring] Filter와 Interceptor의 차이점  (0) 2022.09.08
[Spring] @Controller와 @RestController  (0) 2022.08.31
[Spring] File Download  (0) 2022.08.25
728x90

1. 라이브러리 연동

 

https://code.jquery.com/jquery-3.6.0.min.js
https://cdnjs.com/libraries/jquery   - cdn 방식의 라이브럴
1- 다운받아 오프라인으로 작업
2- CDN방식으로 script 태그로 배치

 


2. 선택자 Selector


요소 선택 : $() 안에 문자형 데이터로 CSS 선택자 입력
ex. $("선택자").css("스타일속성명","값");
    $("선택자").attr("속성명","값"); align, tag등

기본 작성방법
#1. 문서 객체 먼저 불러와 선택자 사용 * 2번보단 1번 추천 (오류덜남)

<script>
    $(document).ready(function(){
   		 //jquery 작성 영역
   		 $("선택자").css("스타일속성명","값");
    });
</script>



#2. 즉시 함수로 묶기

    $(function(){
        //jquery 영역
    });

 

2 - 1 기본선택자

전체 선택자  $("*")
아이디 $("#아이디값")
클래스 $(".클래스값")
태그 $("태그명")
여러개 $("선택1, 선택2, 선택3....")
종속 $("태그명#아이디값")$("태그명.클래스값")$("h1.test.abc")
부모 $("선택").parent() .parents() 
하위 $("기준선택 요소선택")
자식 $("선택 > 자식")
  $("선택").children("자식")
형/동생 $("선택").prev() 형               .prevAll()
  $("선택").next() 동생          .nextAll()
  $("선택+ 요소")
전체 형제  $("선택").siblings()
가장 가까운 상위 $("선택").closest("요소")

 

 

2 - 2 속성선택자

선택한 요소를 기준으로 일치하는 속성의 포함여부를 따져 요소를 선택

 

$("선택[속성]")  선택요소중 지정한 속성이 포함된 요소 선택
$("선택[속성^=값]")  속성값이 지정한 값으로 시작하는 요소 선택 
$("선택[속성$=값]") 속성값이 지정한 값으로 끝나는 요소 선택
$("선택[속성*=값]") 속성값이 이러한 값으로 포함하는 요소 선택
$(":type 속성값") input태그 중 type 속성값이 일치하는 요소 선택
$("선택:visible") 보이는 상태의 요소만 선택
$("선택:hidden") 숨긴 상태의 요소만 선택
$("선택:selected") 선택된 상태의 요소만 선택
$("선택:checked") 체크된 상태의 요소만 선택

 

 

2 - 3 탐색선택자


$("선택").not(:제외요소)
$("선택").find(:"요소선택") : 기준으로 선택한 요소중 지정한 요소만 선택

728x90
728x90

DB 쿼리문을 돌려야하므로 테스트 실행불가

 

 

 

<form>
	<input type="text" name="u_id" />
	<input type="button" value="아이디 중복 확인" onclick="openConfirmId(this.form)"/>
 </form>
    
    
  <script>
    function openConfirmId(inputForm) {
	         if(inputForm.u_id.value == ""){
	            alert("아이디를 입력하세요.");
	            return;    // 이 함수 강제종료
	         }
	         // 검사 팝업 열기 
	         let url = "confirmId.jsp?u_id=" + inputForm.u_id.value;         
	         open(url, "confirmId", "width=300, height=200, toolbar=no, location=no, status=no, menubar=no, scrollbars=no, resizable=no"); 
	      }
  </script>

 

 

 

 

// confirmId.jsp



<%@page import="team.user.model.UserDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>아이디 중복확인</title>
</head>
<%
	request.setCharacterEncoding("UTF-8"); 
	// open(url...) : url = confirmId.jsp?u_id=값
	String u_id = request.getParameter("u_id");
	// DB 연결해서 사용자가 작성한 id값이 db테이블에 존재하는지 검사 
	UserDAO dao = new UserDAO(); 
	boolean result = dao.confirmId(u_id); // true 이미존재함, false 존재X -> 사용가능 
%>
<body>
<%
	if(result) { // true -> 이미 존재 -> 사용불가  %>
	<br />
	<table>
		<tr>
			<td><%= u_id%>은/는 이미 사용중인 아이디 입니다.</td>
		</tr>
	</table> <br />
	<form action="confirmId.jsp" method="post">
		<table>
			<tr>
				<td> 다른 아이디를 선택하세요. <br />
					<input type="text" name="u_id" /> 
					<input type="submit" value="아이디 중복확인" />
				</td>
			</tr>		
		</table>
	</form>
		
<%	}else { // false -> 존재 X -> 사용 가능 %>
	
	<br />
	<table>
		<tr>
			<td>입력하신 <%= u_id%>은/는 사용 가능합니다. <br />
				<input type="button" value="닫기" onclick="setU_id()" />
			</td>
		</tr>
	</table>
		
<%	}%>

	<script>
		function setU_id() {
			// 팝업을 열어준 원래 페이지의 id input태그의 value를
			// 최종 사용할 id로 변경. 
			opener.document.inputForm.u_id.value = "<%= u_id%>";
			// 현재 팝업 닫기. 
			self.close(); 
		}
	</script>
</body>
</html>
// DAO 쿼리문 매서드 


public boolean confirmId(String u_id) {
			boolean result = false;
			int u_idCount = 0;
			Connection conn = null; 
			PreparedStatement pstmt = null;
			ResultSet rs = null; 
			
			try {
				conn = getConnection(); 
				String sql = "select count(*) from signup where u_id=?";
				pstmt = conn.prepareStatement(sql);
				pstmt.setString(1, u_id);
				rs = pstmt.executeQuery();
				if(rs.next()) {
					u_idCount = rs.getInt(1);
					System.out.println("u_idCount : " + u_idCount);
					if(u_idCount == 1) {
						result = true;
					}
				}

				
			}catch(Exception e) {
				e.printStackTrace();
			}finally {
				if(rs != null) try { rs.close();} catch(SQLException e) { e.printStackTrace(); }
				if(pstmt != null) try { pstmt.close();} catch(SQLException e) { e.printStackTrace(); }
				if(conn != null) try { conn.close();} catch(SQLException e) { e.printStackTrace(); }
			}
			
			return result;
		}
728x90
728x90

게시글, 회원가입할때 주로 사용하는 null alert 매서드

 

 

로그인 회원가입
아이디(필수기입)
비밀번호(필수기입)
비밀번호 확인(필수기입)

 

 

 

 

 

 

 <form action="signupPro.jsp" method="post" name="inputForm" enctype="multipart/form-data" onsubmit="return checkField();">
	      <table>
			<tr>
				<td onclick="window.location='loginForm.jsp'"> 로그인 </td>
				<td onclick="window.location='signupForm.jsp'"> <b>회원가입<b></b> </td>
			</tr>	      
	         <tr>
	            <td>아이디(필수기입)</td>
	            <td><input type="text" name="u_id" /> </td>
	         </tr>
	         <tr>
	            <td>비밀번호(필수기입)</td>
	            <td><input type="password" name="u_pw" /></td>
	         </tr>
	         <tr>
	            <td>비밀번호 확인(필수기입)</td>
	            <td><input type="password" name="u_pwck" /></td>
	         </tr>
 			<tr>
	            <td colspan="2">
	               <input type="submit" value="회원가입" /> 
	               <input type="reset" value="재작성" /> 
	               <input type="button" value="취소" onclick="window.location='/team/banner/main.jsp'" />
	            </td>
	         </tr>
	      </table>
   </form>



	<script>
		function checkField(){
			let inputs = document.inputForm;
			if(!inputs.u_id.value){	// name속성이 id인 요소의 value가 없으면 true
				alert("아이디를 입력하세요.");
				return false;	// pro페이지로 이동 금지.
			}
			if(!inputs.u_pw.value){	
				alert("비밀번호를 입력하세요.");
				return false;
			}
			if(!inputs.u_pwch.value){
				alert("비밀번호 확인란을 입력하세요.");
				return false;
			}		
			if(inputs.u_pw.value != inputs.u_pwch.value){
				alert("비밀번호가 일치하지 않습니다.");
				return false;
			}
		}
	</script>

	  
</body>
	</html>
728x90
728x90

체크박스 선택시 제출버튼 활성화

 

 

 

 

 

 

 

Insert title here
[필수] 체크해야 제출가능

 

 

 


<form action="#" method="#" name="#" enctype="multipart/form-data" onsubmit="#">
	<input type="checkbox" name="agreements" onClick="agreeCheck(this.form)"> [필수] 체크해야 제출가능
	<input type="submit"  name="checkButton" value="등록하기"  disabled/>
</form>

<script>
    function agreeCheck(frm){
               if (frm.checkButton.disabled==true)
                frm.checkButton.disabled=false
               else
                frm.checkButton.disabled=true
     }
</script>

 

 

여러개의 경우

https://codesandbox.io/s/agreement-l5uc6?file=/src/index.js

728x90
728x90

버튼에다가 alert만 띄우면 파라미터가 넘어가질 않는데

 

submit에 alert 효과 만들기

 

<form action="#">
	<input type="text"/>
	<input type="file"/>
    <input type="submit" value="수정하기" onClick='return confirmSubmit()'/>
</form> 
    
    
    <script>
		function confirmSubmit()
		{
		var agree=confirm("정말 수정하시겠습니까?");
		if (agree)
			return true ;
		else
			return false ;
		}
	</script>

 

 

 

728x90
728x90

 1. MultipartRequest 객체 생성시, 필요한 인자들
      1. request 내장 객체 (jsp에 이미 있다)
      2. 업로드 될 파일 저장 경로 
      3. 업로드 할 파일 최대 크기
      4. 인코딩 타입 : UTF-8
      5. 업로드된 파일 이름이 같을경우, 덮어씌우기 방지 객체
    

   2. 브라우저에서 보낸 파일 저장할 서버측의 저장 경로
    2-1. PC에 저장(서버쪽X, 서버가 있는 내PC에 저장)
   String path = "C:\\tmp\\"; (pc에 올리면 웹페이지상에서 볼수가없다 )
   
    2-2 서버상에 저장
   String path = request.getRealPath("save"); // 서버상의 save 폴더 실제 경로 찾기
   System.out.println(path);
   3. 업로드 할 파일 최대 크기
   int max = 1024*1024*5;   // 5mb
   4. 인코딩
   String enc = "UTF-8";
   5. 덮어씌우기 방지 객체
   DefaultFileRenamePolicy dp = new DefaultFileRenamePolicy();
   
   6. MultipartRequest 객체 생성
   MultipartRequest mr = new MultipartRequest(request, path, max, enc, dp);
   
   7. 파라미터 받기
   String writer = mr.getParameter("write");
   String sysName = mr.getFilesystemName("upload");   // 업로드 파일 이름
   String orName = mr.getOriginalFileName("upload");   // 파일 원본 이름
   String contentType = mr.getContentType("upload");   // 파일 종류 : 사진, 글....
   
   
   8.DB에 저장
   UploadDAO dao = new UploadDAO();
   dao.insertData(writer,sysName);
   
   
   

<title>image upload</title>
</head>
<body>
   <h1> form page </h1>
      <form action="upload.jsp" method="post" enctype="multipart/form-data">
         작성자 : <input type="text" name="write" /> <br />
         파  일 : <input type="file" name="upload" /> <br />
                <input type="submit" value="전송" />
      
      </form>

</body>
</html>

 

 

 

<title>upload pro</title>
</head>
<%
   request.setCharacterEncoding("UTF-8");
   /*  MultipartRequest 객체 생성시, 필요한 인자들.
   
      1. request 내장 객체 (jsp에 이미 있다)
      2. 업로드 될 파일 저장 경로 
      3. 업로드 할 파일 최대 크기
      4. 인코딩 타입 : UTF-8
      5. 업로드된 파일 이름이 같을경우, 덮어씌우기 방지 객체
      
      */

   // 2. 브라우저에서 보낸 파일 저장할 서버측의 저장 경로
   // 2-1. PC에 저장(서버쪽X, 서버가 있는 내PC에 저장)
   //String path = "C:\\tmp\\"; (pc에 올리면 웹페이지상에서 볼수가없다 )
   
   // 2-2 서버상에 저장
   String path = request.getRealPath("save"); // 서버상의 save 폴더 실제 경로 찾기
   System.out.println(path);
   // 3. 업로드 할 파일 최대 크기
   int max = 1024*1024*5;   // 5mb
   //4. 인코딩
   String enc = "UTF-8";
   // 5. 덮어씌우기 방지 객체
   DefaultFileRenamePolicy dp = new DefaultFileRenamePolicy();
   
   // MultipartRequest 객체 생성
   MultipartRequest mr = new MultipartRequest(request, path, max, enc, dp);
   
   // 파라미터 받기
   String writer = mr.getParameter("write");
   String sysName = mr.getFilesystemName("upload");   // 업로드 파일 이름
   String orName = mr.getOriginalFileName("upload");   // 파일 원본 이름
   String contentType = mr.getContentType("upload");   // 파일 종류 : 사진, 글....
   
   
   // DB에 저장
   UploadDAO dao = new UploadDAO();
   dao.insertData(writer,sysName);
   
   
   
%>
<body>

   <h2>작성자 : <%=writer%> </h2>
   <h2>업로드 파일명 : <%=sysName%></h2>
   <h2>파일 원본이름 : <%=orName%></h2>
   <h2>컨텐트 타입(파일종류) : <%=contentType%></h2>
	
	<img src="/web/save/<%=sysName%>" width="300px"/>
</body>
</html>
728x90

+ Recent posts