Secret

  • 보안유지가 필요한 자격증명 및 개인 암호화 키 같은 중요한 정보를 저장하고 분류하기 위해 제공되는 리소스

1) 특징

  • 패스워드 같은 기밀 정보를 Base64 인코딩으로 만들 수 있다.
  • key=value 쌍으로 사용한다.
  • 환경 변수로 secret 정보를 컨테이너에 전달할 수 있다.
  • 볼륨의 파일로서 시크릿 정보를 저장할 수 있다.
  • 메모리에 저장된다.
  • 시크릿 크기가 너무 커지면 쿠버네티스의 apiserver나 kubelet의 메모리를 많이 차지하게되기 때문에 개별 시크릿의 최대 크기는 1MB까지 정의한다.

 

2) 종류

  • Built in 시크릿(default-token secret)
    : 클러스터 내부에서 API 이용 시 사용됨
    : 내부에서 사용되는 계정인 Service account를 생성하면 자동으로 secret 생성
    : 만들어진 secret으로 해당 service account가 권한을 가지고 있는 API 접근 가능

  • 사용자 정의 시크릿
    : 말그대로 사용자가 정의한 시크릿
    : create 명령어를 사용하여 생성할 수 있고, yaml 파일에 정의해서 생성할 수도 있음

 

3) Secret vs ConfigMap

  • 민감하지 않은 일반 데이터는 configMap 리소스를 사용한다.
  • 중요 데이터가 포함되어 있으면 Secret 리소스를 사용하는 것이 좋다.

 

4) Built in Secret

  • 모든 Pod에는 자동으로 연결된 secret 볼륨이 존재한다.

 

$ kubectl describe pod [name]

Mounts:

      /var/run/secrets/kubernetes.io/serviceaccount from default-token-kf7wl (ro)


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

Volumes:

  default-token-kf7wl:

    Type:        Secret (a volume populated by a Secret)

    SecretName:  default-token-kf7wl

    Optional:    false

$kubectl describe secret default-token-kf7wl

Name:         default-token-kf7wl

Namespace:    default

Labels:       <none>

Annotations:  kubernetes.io/service-account.name=default

              kubernetes.io/service-account.uid=7223520f-e519-11e9-876a-025000000001


Type:  kubernetes.io/service-account-token


Data

====

ca.crt:     1025 bytes

namespace:  7 bytes

token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4ta2Y3d2wiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjcyMjM1MjBmLWU1MTktMTFlOS04NzZhLTAyNTAwMDAwMDAwMSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.P4FnIdYC_JHXCM-RyboMkotOEkf2sRhRgXkyS9nUezIOddQ3lQGdsPI8ZXiIq1PPZN2KrXUMjq6B7rDJw3_A-zN2e1UwQfemPqllhrSNduy1WWwJTCsv71rjZmLrmrA5klmgW7DzizfLNgKY6hLpK7lSlA3pxIDzkdtYhG9AQ4oXPTym6LUCgPCO2DhonMVbbkQtRI2JoWvCdxS6geea-Kne4Op82lWFErv5zP0hmUhb5vyiFXGWBQYp-CZehiwAuNNg44_cyz3d6r_51oJAwcKiovxPRkqjJqiJfxG5gjDlPu6GT9Enbbh5Jo2x3hHYXwBqOV8CV0iT7ZyU_p2eEA


 

 

 

 

 

=> secret volume을 통해 제공되는 3가지 항목은 kubenetes API 서버와 안전하게 통신하기 위해 필요하다.

=> 즉 https 통신을 하기 위함

key

설명

ca-crt

certificate-authority , 인증서

 

 

5) 사용자 정의 시크릿

  • mac이나 linux에서 다음과 같은 명령어로 문자열을 base64로 인코딩 할 수 있다.

  • base64로 인코딩하는 이유는 ssl인증서나 binary 데이터의 지원을 위해 사용된다.

 

$ echo password | base64

cGFzc3dvcmQK

 

 

5.1) 시크릿 생성 - 명령어

$ echo -n ‘sa’ > ./username.txt
$ kubectl create secret generic h2-user-name --from-file=./username.txt

 

 

5.2) 시크릿 생성 - yaml 파일

apiVersion: v1
kind: Secret
metadata:
 name: mysqlsecret
type: Opaque
data:
 MYSQL_USER: cm9vdAo=
 MYSQL_PASSWORD: cm9vdAo=
in:/sbin:/bin



 

$ kubectl describe secret mysqlsecret

Name:         mysqlsecret
Namespace:    default
Labels:       
Annotations:  
Type:         Opaque

Data
====
MYSQL_PASSWORD:  5 bytes
MYSQL_USER:      5 bytes


Opaque 및 타입에 대해 알아보기

https://github.com/kubernetes/kubernetes/blob/7693a1d5fe2a35b6e2e205f03ae9b3eddcdabc6b/pkg/apis/core/types.go#L4394-L4478

 

 

5.3) 시크릿 적용

<simple-database-secret.yaml>

apiVersion: v1
kind: Secret
metadata:
 name: mysqlsecret
type: Opaque
data:
 MYSQL_USER: cm9vdAo=
 MYSQL_PASSWORD: cm9vdAo=in:/sbin:/bin

apiVersion: v1
kind: ConfigMap
metadata:
 name: database-config
data:
 MH_ADDR: "192.168.137.100"
 MYSQL_PORT: "3306"
 MYSQL_DATABASE: "sample"

---

apiVersion: apps/v1
kind: Deployment
metadata:
 name: health-check-app
 labels:
   app: healthcheck-test
spec:
 replicas: 1
 selector:
   matchLabels:
     app: healthcheck-test
 template:
   metadata:
     labels:
       app: healthcheck-test
   spec:
     containers:
       - name: health-check-app
         image: chulm/health-check-app:latest
         envFrom:
           - configMapRef:
               name: database-config
         env:
           - name: MYSQL_USER
             valueFrom:
               secretKeyRef:
                 name: mysqlsecret
                 key: MYSQL_USER
           - name: MYSQL_PASSWORD
             valueFrom:
               secretKeyRef:
                 name: mysqlsecret
                 key: MYSQL_PASSWORD
         ports:
           - containerPort: 8080

 

 

5.4) 환경변수 조회

$ kubectl exec health-check-app-86758956dd-lqb2t -- env | sort

 

....

KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
LANG=C.UTF-8
MH_ADDR=192.168.137.100
MYSQL_DATABASE=sample
MYSQL_PASSWORD=root
MYSQL_PORT=3306
MYSQL_USER=root

 

 

참조: https://kubernetes.io/docs/concepts/configuration/secret/

namespace

 쿠버네티스는 클러스터 안에 가상 클러스터를 또 만들 수 있다.

- kubectl get namespace

 

 

pod

 

1) yaml 파일 정의해서 생성하기

 

simple-pod.yaml

apiVersion: v1

kind: Pod

metadata:

 name: health-check-app

spec:

 containers:

   - name: health-app

     image: chulm/health-check-app:latest

     ports:

       - containerPort: 8080

 

 

key

설명

kind

쿠버네티스 리소스의 유형을 지정

metadata

쿠버네티스 리소스의 메타데이터 지정

spec

리소스를 정의하는 속성



$ kubectl apply -f simple-pod.yaml

 

2) pod 정보 조회

$ kubectl get pod

$ kubectl get pods --all-namespaces -o wide



3) pod 내부 컨테이너 실행

$ kubectl exec -it health-check-app sh -c health-app

 

4) 로그 보기

$ kubectl logs health-check-app

 

5) pod 삭제

$ kubectl delete pod health-check-app

 

6) 리소스 전체 삭제

$ kubectl delete -f simple-my-pod.yaml



7) 로컬 포트 포워딩

$ kubectl port-forward health-check-app 8080:8080 

 

replicaset

: 똑같은 정의를 갖는 파드를 여러 개 생성하고 관리하기 위한 리소스

 

simple-replicaset.yaml

apiVersion: apps/v1

kind: ReplicaSet

metadata:

 name: health-check-app

 labels:

   app: healthcheck-test

   environment: dev

spec:

 replicas: 3

 selector:

   matchLabels:

     app: healthcheck-test

 template:

   metadata:

     labels:

       app: healthcheck-test

   spec:

     containers:

       - name: health-check-app

         image: chulm/health-check-app:latest

         ports:

             - containerPort: 8080

 

 

key

설명

label

쿠버네티스의 리소스를 선택하는데 사용한다.

template

template 속성의 내용은 pod 메타데이터의 정의와 같다.

selector

라벨 조건을 정의, equality based selector와 set based selector가 존재


  1. equality based selector로 pod 조회


: 등가로 표현 (= , !=)

  • kubectl get pod -selector app=healthcheck-test


:약식으로는 -l 옵션으로 조회

  • kubectl get pod -l  app=healthcheck-test


  1. set based selector로 pod 조회 

: 집합형태로 표현 

  • kubectl get pod -l  ‘app in (healthcheck-test, other)’



 

1) replicaset 생성

 $ kubectl apply -f [file]

 

2) label 조회

$ kubectl get pods --show-labels

 


NAME                           READY STATUS RESTARTS AGE       LABELS

health-check-app-hng7g   1/1 Running 0       1m app=healthcheck-test

health-check-app-klg9q    1/1 Running 0     1m app=healthcheck-test

health-check-app-v6rhz    1/1 Running 0     1m app=healthcheck-test


3) replicatset 삭제

$ kubectl delete rs health-check-app --cascade=false 

  : cascade default는 true, pod이 삭제됨

 

4) pod 삭제할 경우

  : replicaset에 의해 복제된 개수가 유지되기 때문에 자동으로 Pod을 추가 생성




deployment

  : 애플리케이션 배포의 기본 단위가 되는 리소스, rs의 상위 리소스

 

simple-deployment.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

 name: health-check-app

 labels:

   app: healthcheck-test

   environment: dev

spec:

 replicas: 3

 selector:

   matchLabels:

     app: healthcheck-test

 template: ### template 아래는 pod 리소스 정의와 같음.

   metadata:

     labels:

       app: healthcheck-test

   spec:

     containers:

       - name: health-check-app

         image: chulm/health-check-app:latest

         ports:

           - containerPort: 8080




  • deployment 리소스는 replicaSet 리소스를 관리한다.

https://www.pinterest.co.kr/pin/825003225467521861/

  • replicaSet의 리소스를 수정한다고 해서 revision이 변경되지는 않는다.

: 예로 replicas의 개수를 수정한다고 배포의 revision은 바뀌지 않으며, replicaSet만 변경된다.

 

  • 컨테이너를 변경하고 재 배포하면, 기존 컨테이너는 중지되고 revision 이 2가 된다.

$ kubectl rollout history deployment health-check-app 

deployments "health-check-app"

REVISION  CHANGE-CAUSE

1         kubectl apply --filename=simple-my-deployment.yaml --record=true

2         <none> (--record 옵션을 주지 않으면 명령어가 기록되지 않음)



1) yaml 파일 정의해서 생성하기
$ kubectl apply -f simple-deployment.yaml --record

(명령 실행 기록을 남기는 --record 옵션)

 

2) deployment revision 확인

$ kubectl rollout history deployment health-check-app
$ kubectl rollout history deployment health-check-app --revision=1

 

3) rollback 하기

$ kubectl rollout undo deployment health-check-app
$ kubectl rollout undo deployment health-check-app  --revision=1

 

4) deployment  진행 상태 확인

$ kubectl rollout status deployment health-check-app

 

5) deployment 상세 확인

$ kubectl describe deployment health-check-app 

 

service

: po의 집합(주로 rs)에 대한 서비스 디스커버리를 제공하는 리소스
: service의 대상이 되는 pod는 label selector로 정해진다.

 

  • service type 4가지가 존재함.
    cluster IP : cluster IP 생성

Node Port : cluster IP 생성 및 global port 개방
load Balancer : 로컬 환경에서는 사용 할 수 없음. 주로 클라우드 플랫폼에서 사용
external name : 셀렉터 및 포트 정의 하지 않음. externalName만으로 접근



simple-service.yaml

apiVersion: v1

kind: Service

metadata:

 name: healthcheck-nodeport

spec:

 type: NodePort

 ports:

   - port: 8080

     targetPort: 8080

 selector:

   app: healthcheck-test   ##label과 연결

 

1) service 조회
$ kubectl get svc

 

ingress

service로 nodePort를 노출시킬 때, l4(tcp) 레벨까지만 다룰 수 있기 때문에 http/https 경로를 기반으로 서비스를 전환하는 l7 레벨의 제어는 불가능하다. 이를 해결하기 위한 리소스가 ingress이다.

로컬 환경에서는 인그레스를 사용해 서비스를 노출 시킬 수 없기 때문에 nginx_ingress_controller를 다음과 같이 배포해야 한다.

 

1) ingress-nginx의 배포

-namespace

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

- service, pod

$kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud-generic.yaml

 

2) ingress-nginx의 service와 pod 조회

$ kubectl -n ingress-nginx get svc, pod

 

NAME                    TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx   LoadBalancer   10.106.139.137   localhost     80:32144/TCP,443:30813/TCP   14m

NAME                                            READY     STATUS    RESTARTS   AGE
pod/nginx-ingress-controller-75cb46c787-t48kr   1/1       Running   0          16m

 

3) simple-svc.yaml 생성 및 실행

apiVersion: v1
kind: Service
metadata:
name: healthcheck-svc
spec:
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app: healthcheck-test

 

$ kubectl apply -f simple-svc.yaml

 

 

4) simple-ingress.yaml 생성 및 실행

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: healthcheck-ingress
spec:
rules:
- host: com.k8s.myapp
http:
paths:
- path: /
backend:
serviceName: healthcheck-svc
servicePort: 8080

 

 

 

$ kubectl apply -f simple-ingress.yaml

 

5) 테스트

$  curl http://localhost/healthCheck -H 'Host: com.k8s.myapp' 

 

> 결과

 

'Cloud & NoSQL & Middleware > Kubernetes' 카테고리의 다른 글

kubernetes - secret  (0) 2019.10.11
쿠버네티스 배경 및 입문  (0) 2019.09.03

Reflection

- Java에서 지원하는 API로, 객체를 통해 클래스의 정보를 분석해 낼 수 있다.
- 즉, 실행중인 Java Application의 Class 정보를 동적으로 접근하여 메소드, 필드 등에 접근하거나 인스턴스를 다룬다.

- 대표적인 예로 Spring의 Bean들은 Reflection을 통해 인스턴스들이 다뤄진다.

 

실제로 org.springframework.beans.annotation.AnnotationBeanUtils 클래스 내부를 보면 bean의 properties를 copy하는 메소드를 찾을 수 있는데, Object 타입의 bean과 java.lang.reflection.Method를 통해 bean의 메소드들이 다뤄지는 것을 확인할 수 있다.

/**
	 * Copy the properties of the supplied {@link Annotation} to the supplied target bean.
	 * Any properties defined in {@code excludedProperties} will not be copied.
	 * <p>A specified value resolver may resolve placeholders in property values, for example.
	 * @param ann the annotation to copy from
	 * @param bean the bean instance to copy to
	 * @param valueResolver a resolve to post-process String property values (may be {@code null})
	 * @param excludedProperties the names of excluded properties, if any
	 * @see org.springframework.beans.BeanWrapper
	 */
	public static void copyPropertiesToBean(Annotation ann, Object bean, @Nullable StringValueResolver valueResolver,
			String... excludedProperties) {

		Set<String> excluded = new HashSet<>(Arrays.asList(excludedProperties));
		Method[] annotationProperties = ann.annotationType().getDeclaredMethods();
		BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(bean);
		for (Method annotationProperty : annotationProperties) {
			String propertyName = annotationProperty.getName();
			if (!excluded.contains(propertyName) && bw.isWritableProperty(propertyName)) {
				Object value = ReflectionUtils.invokeMethod(annotationProperty, ann);
				if (valueResolver != null && value instanceof String) {
					value = valueResolver.resolveStringValue((String) value);
				}
				bw.setPropertyValue(propertyName, value);
			}
		}
	}

 

 

샘플 예제

 

간단하게 샘플 예제를 구현해보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
 
class Calculator {
    private String name;
      
    public Calculator() {
        System.out.println("call Calculator()");
    }
    
    public int add(int a, int b) {
        System.out.println("call add()");
        int result = a + b;
        return result;
    }
    public int minus(int a, int b) {
        System.out.println("call minus()");
        int result = a - b;
        return result;
    }
}
 
public class ReflectionTest {
    
    public static void main(String[] args) throws Exception {
    
        
        Class<?> cls = Class.forName("Calculator");
        
        Field[] fields = cls.getDeclaredFields();
        
        for(Field field: fields) {
            System.out.println("field="+field.getName());
        }
        
        Calculator calculator = new Calculator();
        Method[] methods = cls.getDeclaredMethods();
        
        for(Method method: methods) {
            Object s = method.invoke(calculator, 4,3);
            System.out.println("result=" + s);
        }
        
        System.out.println("Class="+cls.getName());
    }
 
}
 
cs

 

field=name

call Calculator()

call add()

result=7

call minus()

result=1

Class=Calculator

 

 

 

 

장점

 

확장: 확장 가능한 인스턴스를 만들어 외부 사용자 정의 클래스를 작성 할 수 있다.
디버깅 및 테스트: 디버거는 리플렉션 속성을 사용하여 클래스의 private memeber를 체크할 수 있다.

 

 

단점

 

성능 : reflection은 성능이 느리므로 성능에 민감한 프로그램이라면, 자주 호출되는 코드에서는 피하는 것이 좋다.
내부 노출 : reflection은 클래스 추상화를 손상 시킬 수 있다. 즉, 클래스 코드의 변경이 있으면 동작의 변경이 따를 수 있다.

 

 

 

https://docs.oracle.com/javase/tutorial/reflect/index.html

 

Trail: The Reflection API (The Java™ Tutorials)

Uses of Reflection Reflection is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the Java virtual machine. This is a relatively advanced feature and should be used only by developers

docs.oracle.com

 

배경

 

시대가 변함에 따라, 과거 모놀로틱 아키텍쳐의 많은 서비스를 거쳐 많은 프로젝트들이 MSA 기반의 트렌드로 변하고 있다.

이에 따라 애플리케이션들은 물리 서버 혹은 물리 서버의 VM(Virtual Machine)을 지나 도커와 같은 컨테이너 기반의 가상화 플랫폼위의 컨테이너에 존재하는 시대가 되었다.

 

 

 

Container Orchestration

컨테이너는 애플키에션을 포장하고 실행하며 관리하기에 좋은 도구이다. 하지만 컨테이너의 확장에 따라 이러한 컨테이너들의 관리해줄 도구가 분명 필요하다. 즉 간단하게 말해서 쿠버네티스는 컨테이너 관리 도구라고 생각하면 쉽다.

 

Apache Mesos, Docker Swarm, ECS 등 다양한 Container Orchestration이 존재하지만 확실하게 쿠버네티스는 높은 수준의 관리 기능을 제공해 주는 인기있는 툴이다.

 

 

Kubernetes

- 구글에서 15년간 프로덕션 워크로드 운영한 경험을 토대로 구축

- 컨테이너 운영을 자동화하기 위한 컨테이너 오케스트레이션 도구

- 약어 K8s ( k와 s 사이에 8글자라서.. 하하^^), Kube 등으로 불림

- 많은 수의 컨테이너를 협조적으로 연동하기 위한 통합 시스템

- 명령어 도구 kubectl 제공

- 러닝 커브가 좀 높다.

 

 

특징

  1. Service Discovey
    : 쿠버네티스는 DNS 및 자체 IP를 사용하여 컨테이너를 노출한다.
  2. load Balancing
     : 컨테이너의 트래픽이 많으면 로드밸런싱을 하여 배포한다.
  3. Storage Orchestraion
    : 로컬 저장소 및 클라우드와 시스템과 연동 및 자동 탑재한다.
  4. Self-Healing
    : 문제가 발생한 컨테이너를 자동 재시작한다.
  5. Automated rollout and rollback
    : 컨테이너의 원하는 상태를 서술하며 언제든지 변경가능하다.
  6. Batch execute
    : 스케쥴러 배치 작업이 가능하다. 
  7. Horizontal Scaling
    : CPU 사용에 따라서, 명령어 혹은 UI 등과 함께 Scale Up and Down이 가능하다.
  8. Docker Host Management

 

 

 

참고

 https://kubernetes.io/ko/docs/concepts/overview/what-is-kubernetes/

'Cloud & NoSQL & Middleware > Kubernetes' 카테고리의 다른 글

kubernetes - secret  (0) 2019.10.11
kubernetes - pod, rs, svc, deployment, ingress  (0) 2019.10.03

AOP

  • 관점 지향 프로그래밍(Aspect Object Programming)

  • 횡단 관심사 (CrossCutting)

  • Pure Java로 구현

  • OOP 모듈의 핵심단위가 클래스라면, AOP 모듈의 핵심단위 Aspect 이다.

  • Spring IOC 컨테이너는 AOP에 의존하지 않는다.

개념

  • Aspect: 여러 클래스에 부가되는 영향을 미치는 모듈. @Aspect 혹은 aspect 구현 클래스. 가장 좋은 예는 transaction

  • Join point: 메소드의 실행이나 예외 처리 같은 프로그램의 실행 중의 지점

  • Advice: 특정 조인 포인트에서 Aspect에 의해 취해지는 액션. around, before, after .

  • Pointcut: 어드바이스를 적용할 조인포인트의 선별 기능을 정의한 모듈.

    • 포인트 컷 표현에 의해 일치하는 조인포인트를 구별하는게 스프링 aop의 핵심이며, aspectJ pointcut 표현식을 사용한다.

  • Target object: 하나 혹은 여러 aspect에 의해 advised된 object. 항상 runtime proxies에 의해 구현되므로 proxied object 이다.

  • Introduction: advised object에 추가적인 메소드 및 필드를 선언할 수 있다.

  • AOP proxy: 타겟 객체를 감싸서 타겟의 요청을 대신 받아주는 오브젝트. 타겟 실행 전, 후 처리 

    • 프록시는 타겟의 요청을 가로챈 후 advise를 먼저 실행하며 이후 타겟 메소드를 실행한다.

  • Weaving: 지정된 객체에 aspect를 적용해서 새로운 advised 객체를 생성하는 과정. 런타임에 위빙이 수행된다.

advice type

  • Before advice : join point 전에 실행되는 advice. 예외를 던지지 않는 한 join point가 실행되는 것을 막을 수는 없다.

  • After returning advice : join point가 정상적으로 완료된 후 실행되는 advice

  • After throwing advice: 메소드가 예외를 throw하고 종료되면 실행되는 advuce

  • After (finally) advice: return 혹은 예외와 관계없이 join point 이 후 무조건 실행되는 advice

  • Around advice : 메소드 호출과 같이 join point를 감싸는 advice

    • 가장 강력한 advice
    • 메소드 호출 전 혹은 후 사용자 정의 동작을 정의할 수 있음
    • 조인 포인트에서 계속 수행할지 혹은 return이나 예외를 Throw하여 advice를 선택할지 정할 수도 있다.

Around Advice

  • Around Advice는 모든 유형의 advice를 제공하는 가장 일반적이고 강력한 advice이다.
  • 스프링에서 왠만하면 Around Advice를 사용하기를 권고한다.

핵심

  • 포인트 컷에 의해 매칭되는 조인포인트의 개념이 AOP의 핵심이다.
  • 포인트 컷은 객체지향 구조와 독립적으로 advice를 가능하게 한다.
  • 예를 들면.. 선언적 transaction management

https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop

https://db-engines.com/en/ranking

'기타' 카테고리의 다른 글

동시성 관련 기본 용어  (0) 2020.03.14
nginx configuration  (0) 2020.01.07
Ant vs Maven Vs Gradle  (0) 2019.04.10
Thread 분석  (0) 2018.11.19
Oracle JDK 유료화의 논쟁, OpenJDK와의 차이  (0) 2018.11.03

 

 

 

Zuul은 Frontend로 부터 모든 요청을 받아 내부 마이크로서비스들에게 요청을 전달하므로 단일 종단점을 갖게하는 API Gateway 와 같은 역할을 수행한다. zuul 필터에 의해 다음과 같은 기능을 수행할 수 있다.

 

- CORS

- 인증

- 보안

- 라우팅

- 프록시

 

 

 

zuul filter

 

Zuul Filter는 크게 4가지 Filter로 나누어 진다.

  1. PRE Filter - 라우팅전에 실행되며 필터  ex) 인증
  2. ROUTING Filter - 요청에 대한 라우팅을 다루는 필터 ex) ribbon을 통한 라우팅
  3. POST Filter - 라우팅 후에 실행되는 필터 ex) resoponse에 대한 처리
  4. ERROR Filter - 에러 발생시 실행되는 필터

 

 

 

 

https://medium.com/netflix-techblog/announcing-zuul-edge-service-in-the-cloud-ab3af5be08ee

 

Announcing Zuul: Edge Service in the Cloud

the latest addition to Netflix’s Open Source Software suite

medium.com

 

https://github.com/Netflix/zuul/wiki/How-We-Use-Zuul-At-Netflix

 

Netflix/zuul

Zuul is a gateway service that provides dynamic routing, monitoring, resiliency, security, and more. - Netflix/zuul

github.com

 

'Framework > Spring ' 카테고리의 다른 글

Spring AOP (1)  (0) 2019.08.02
Spring Cloud Netflix (2) - hystrix  (0) 2019.02.25
Spring Cloud Netflix (1) - OverView  (0) 2019.02.10
Spring Websocket (Handler, STOMP, Reactive Websocket)  (6) 2019.02.10

 

최소 지원 브라우저 버전 

 

 

 

 

Overview

 

  • HTTP/2 프로토콜은 클라이언트와 서버간 연결(on the wire)에서 HTTP 어떻게 표현되는지로 대체됨
  • 프로토콜의 초점은 성능
    -
    사용자(end-user) 지연시간(latency) 네트워크와 서버 자원의 사용을 감지
  • connection 맺으면 최대한 길게 사용할 것을 권고

    연결 수가 적다는 것은 HTTPS 배포의 성능을 개선하는데 특히 중요. 연결 수가 적으면 비용이 많이 발생하는 TLS 핸드셰이크가 줄어들고, 세션 재사용이 향상되며, 필요한 클라이언트 서버 리소스가 감소

  • 서버가 HTTP2 프로토콜을 지원할 경우 101 switching protocol 응답 받으며 연결되며, 지원하지 않을 경우 연결하기 위한 특정 header(Connection and Upgrade) 무시하고 HTTP 1.x 프로토콜로 FALL BACK 해야 한다.



Stream, Message, Frame

- http2의 기본 구성 요소는 Stream, Message, Frame 이다.

 

 

 

  • 스트림: 구성된 연결 내에서 전달되는 바이트의 양방향 흐름이며, 하나 이상의 메시지가 전달될 있다.
  • 메시지: 논리적 요청 또는 응답 메시지에 매핑되는 프레임의 전체 시퀀스
  • 프레임: HTTP/2에서 통신의 최소 단위이며 최소 단위에는 최소 하나의 프레임 헤더가 포함된다. 프레임 헤더는 최소한 프레임을 통해 스트림을 식별한다.


Binary Framing

Http Header와 Body가 Headers Frame, DATA frame으로 변경

 

- Frame은 String 데이터가 Binary로 Framing 된다. 프로토콜은 다음과 같다.

 

 

 

Protocol 

 

  • 모든 프레임은 9 바이트 헤더로 시작한다.(Length + type + flags)
  • Length :  payload 길이를 나타내고 unsigned 24bit integer이다. 수신자가 SETTINGS_MAX_FRAME_SIZE에서 2^14(16,384)보다 값을 설정하지 않았다면 이보다 값이 보내질 없다.
  • Type : 프레임의 형식
  • Flags : 8 비트, 특정 유형의 bool flag. 플래그들은 프래임의 타입에 따라 의미가 달라진다. 특정 프레임 타입에서 의미가 없는 플래그는 무시되어야 하고, 돌려 보낼떄 0으로 unset되어 보내져야한다.
  • R: 1비트 항상 0으로 예약된다.
  • Stream Identifier : 스트림의 식별자

 

Type 

DATA(0) - Used to transport HTTP message bodies

HEADERS(1) - Used to communicate header fields for a stream

PRIORITY(2) - Used to communicate sender-advised priority of a stream

RST_STREAM(3) - Used to signal termination of a stream

SETTINGS(4) - Used to communicate configuration parameters for the connection

PUSH_PROMISE(5) - Used to signal a promise to serve the referenced resource

PING(6) - Used to measure the roundtrip time and perform "liveness" checks

GOAWAY(7) - Used to inform the peer to stop creating streams for current connection

WINDOW_UPDATE(8) - Used to implement flow stream and connection flow control : 흐름 제어

CONTINUATION(9) - Used to continue a sequence of header block fragments

 

 

 

 

 

 

 

 

 

 

Http2는 이외에도 Server push, multiplexing 스트림 우선순위 지정 등 눈여겨 봐야 할 여러가지 특징이 있다. 결론적으로 http2는 http의 느리고 header packet의 중복 전송 등의 단점을 극복할 수 있는 프로토콜이다. 만일 리소스가 많지 않은 서버의 경우 http2는 비효율적일 수 있다. 

 

 

http2 기반 서버 / 클라이언트 구현 예제 샘플 : https://github.com/chulman/netty-http2

 

 

 

 

https://tools.ietf.org/html/rfc7540

 

RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)

[Docs] [txt|pdf] [draft-ietf-http...] [Tracker] [Diff1] [Diff2] [IPR] [Errata] PROPOSED STANDARD Errata Exist Internet Engineering Task Force (IETF) M. Belshe Request for Comments: 7540 BitGo Category: Standards Track R. Peon ISSN: 2070-1721 Google, Inc M.

tools.ietf.org

https://developers.google.com/web/fundamentals/performance/http2/?hl=ko

 

HTTP/2 소개  |  Web Fundamentals  |  Google Developers

HTTP/2(또는 h2)는 푸시, 다중화 스트림 및 프레임 제어를 웹에 구현하는 바이너리 프로토콜입니다.

developers.google.com

 

'Architecture & Protocol' 카테고리의 다른 글

12 요소 애플리케이션 방법론  (0) 2019.02.21
Websocket Protocol 분석  (0) 2019.01.28
서비스 지향 아키텍쳐(SOA)  (0) 2018.12.30
마이크로서비스 아키텍처(MSA)  (0) 2018.12.02

+ Recent posts