Gradle


compile('org.springframework.boot:spring-boot-starter-data-redis')

compile group: 'redis.clients', name: 'jedis', version: '2.9.0'







application.properties 설정


spring.cache.type=redis

spring.redis.host = 127.0.0.1 

spring.redis.password= 

spring.redis.port=6379








RedisConfig 클래스 생성


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
50
51
52
53
54
package com.example.service.redis;
 
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
 
import redis.clients.jedis.JedisPoolConfig;
 
@Configuration
@ComponentScan("com.spring.redis")
public class RedisConfig {
 
    private @Value("${spring.redis.host}"String redisHost;
    private @Value("${spring.redis.port}"int redisPort;
    private @Value("${spring.redis.password}"String password;
 
    @Bean
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(30);
        jedisPoolConfig.setMinIdle(10);
        jedisPoolConfig.setTestOnBorrow(true);
        jedisPoolConfig.setTestOnReturn(true);
        return jedisPoolConfig;
    }
 
    @SuppressWarnings("deprecation")
    @Bean
    public JedisConnectionFactory redisConnectionFactory() {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig());
        jedisConnectionFactory.setHostName(redisHost);
        jedisConnectionFactory.setPort(redisPort);
        jedisConnectionFactory.setPassword(password);
        jedisConnectionFactory.setUsePool(true);
        return jedisConnectionFactory;
    }
 
    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory());
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new StringRedisSerializer());
        template.setEnableDefaultSerializer(false);
        template.setEnableTransactionSupport(true);
        return template;
    }
}
cs




Redis Client에서 가장 많이 사용되는 오픈소스는 Jedis/lettuce/Redisson  중 Jedis이다.


많이 쓴다는 것은 곧 그만큼 사용하기 쉽고 레퍼런스가 많다는 의미이다.


실제로 Jedis를 통해 손쉽게 사용할 수 있었다.


Spring에서 RedisTemplate을 통해 데이터에 엑세스할 뿐 아니라 ConnectionPool의 자원 관리 또한 알아서 해준다.


=> 실제론 JedisConnectionFactory를 통해서 수행




RedisTemplate을 통해 다음과 같은 데이터 타입을 다룰 수 있다.

String

@Resource(name="redisTemplate")
private ValueOperations<String, String> valueOperations;

Set

@Resource(name="redisTemplate")
private SetOperations<String, String> setOperations;

Sorted Set

@Resource(name="redisTemplate")
private ZSetOperations<String, String> zSetOperations;

Hashes

@Resource(name="redisTemplate")
private HashOperations<String, String, String> hashOperations;

List

@Resource(name="redisTemplate")
private ListOperations<String, String> listOperations;







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

Redis Library  (2) 2018.11.17
Single Thread  (0) 2018.11.17
Redis 명령어  (0) 2018.08.04
Redis Pub/Sub Model  (0) 2018.07.01
Java에서 Redis 연동 테스트 (jedis)  (0) 2018.07.01

AWK


- 유닉스에서 처음 개발된 일반 스크립트 언어이다.

- awk는 짧은 프로그램을 구현하기 위해 개발되었다.

- 복잡한 프로그램을 작성하지 않고 파일에 대한 패턴 처리를 쉽게 할 수 있다.

- 필드를 자유자재로 조작하여 데이터 양식의 문서나 자료를 처리하여 다른형태의 문서 또는 결과물로 출력하는데 쓰인다.

- 논리연산, 특수문자, 조건, 반복문 가능


awk [-f prog-file] [-F c] ['pattern {action}'] [filename]  _


1) -f prog-file : awk의 실행 action을 가진 프로그램 파일 지정

2) -F c : 필드 구별자 

3) pattern {action} : awk program의 커맨드는 싱글 쿼트('') 혹은 더블쿼트("")로 둘려 쌓여있으며, action을 중괄호로 둘러싸여있다.

4) _ : awk 프로그램에 입력될 입력 파일 지정



AWK의 내부 변수




ex) awk '{print NF}' test.txt 


ex) awk '/Hello/ {print "%s %10.3f\n", $1, NF}' Hello.txt




ex) jstat -gc [PID] 1000 | awk '{ print "used Memory=", ($3 + $4 + $6 + $8)/1024, "\t\tHeapMemory=",($1 + $2 + $5 + $7)/1024 }'


- awk를 활용한 java 프로그램의 메모리 확인





SED


- Stream Editor의 약자, 비대화모드의 라인 단위 편집기

- Streaming 편집기

- 입력문자 또는 파일에 대해 특별한 기능을 사용하여 변환

- sed는 큰 파일을 처리할 때 주로 사용

- 주어진 주소 범위에 대해 입력의 어떤 라인을 조작할 것인지 결정




sed [-n] [-e script] [-f script_file] [filename]


ex) sed -n '/The/h' Hello.txt


1) [-n] : -n 옵션이 없다면 모든 입력의 출력

2) [-e script] : -e 옵션은 그다음에 나오는 스크립트를 sed 명령어로 해석. 옵션이 없다면 기본으로 지정됨.

3) [-f script_file] : -f 명령어를 통해 명령어를 파일에 저장해놓고 사용가능


   -> sed -n -f scr.sed Hello.txt










'System > Linux,Unix' 카테고리의 다른 글

VI 편집기 명령어 정리  (0) 2018.08.07
명령어 정리  (0) 2018.08.07
Unix의 구조 ( Kernel, Shell)  (0) 2018.08.03
Unix와 Linux의 차이  (0) 2018.08.03
FreeMemory에 대한 이해  (0) 2018.07.17

1.커서 이동





2.입력


1)  i : 현재 커서에서 입력

2) a: 현재 커서 오른쪽에 입력

3) o: 현재 라인의 다음 라인을 공백으로 만듬

4) I: 현재라인의 첫문자 앞에 입력

5) A: 현재 라인의 마지막 뒤에 입력




3. 삭제 


1) x: 다음 글자 삭제

2) X: 앞 글자 삭제

3) dd: 현재 라인 삭제



4. 명령 취소


1) u  : 바로 전에 실행한 명령어 취소

2) U : 현재라인에서 실행한 명령어 전체 취소

3) .  : 앞서 실행했던 명령어 재실행



4. 복사


1) yy : 현재 라인 복사

2) p : 커서 위치 오른쪽 혹은 아래에 붙여넣기




5. 화면이동


1) H: 현재 화면 맨위로 이동

2) L: 현재 화면 맨 아래로 이동

3) M: 현재 화면 중간으로 이동



6. 라인 수 나타내기


: se nu



7. 검색


1) :/pattern : 패턴검색 

:s/pattern1/pattern2 : 패턴1을 패턴2로 검색하고 치환


'System > Linux,Unix' 카테고리의 다른 글

AWK & SED  (0) 2018.08.07
명령어 정리  (0) 2018.08.07
Unix의 구조 ( Kernel, Shell)  (0) 2018.08.03
Unix와 Linux의 차이  (0) 2018.08.03
FreeMemory에 대한 이해  (0) 2018.07.17

1. 파일 정보 관련 명령어



  • umask


- 기본적으로 새로운 파일이 생성될 때 아스키 파일은 허가모드가 644 실행파일은 755로 설정됨.   시스템 내부에 umask 기본값이 022로 설정


  • chown 

- 파일 소유자를 바꿀 수 있다.

ex ) chown -R mysql:mysql [directory]



  • touch


- 파일의 날짜 및 시간을 현재 날짜로 설정

ex) touch filename


  • find 

- 찾고자 하는 파일에 대한 기본적인 자료를 가지고 임의의 파일 시스템에서 주어진 조건과 일치하는 파일을 찾는다.


ex)  find / -name *.c -type d -print



  • head

- 파일의 1줄부터 n번째 줄까지 보여줌

ex) head -4 /etc/passwd


  • tail

- 파일의 끝에서 n번째 줄까지 보여줌


    



2. 파일 내용 관련 명령어


  • cat 

- 파일 전체 내용 출력


  • more

- 파일 한화면 단위로 출력한다.

(스페이스키는 한 화면, 엔터는 한라인씩 내려감)


  • grep 

- 파일 내용 중 일치하는 문자를 찾는다.





3. 파일 비교 관련 명령어


  • cmp

- 파일 2개를 비교하여 틀린 위치를 찾는다,.

ex) cmp test.txt test1.txt





4. 파일 압축 관련 명령어 



리눅스(Linux)에서의 파일 압축 개념은 윈도우즈(Windows)에서의 파일 압축 개념에 비해 세분화 되어있다.

 

윈도우즈에서는 보통 압축을 한다하면, zip 등의 방식으로 선택된 파일이나 폴더들을 묶으면서 동시에 압축(compress)을 하는 것을 의미한다.

반면, 리눅스에서는 파일이나 폴더들을 묶는 것(archive)과 실제로 압축(compress)하는 기능이 나뉘어져있다.

 

리눅스에서 여러 파일을 한 파일로 묶은 것을 아카이브(archive)라 하며 확장자는 .tar 이다.

일반적으로 tar로 묶인 아카이브를 gunzip을 사용해서 .tar.gz 의 확장자를 가지는 압축 아카이브로 많이 사용한다.

  • pack 

- 파일을 압축시켜 .z 확장자를 붙인다.

pack test1


  • unpack

- .z 확장자의 파일을 압축해제 한다.

unpack test1.z


  • tar


- .tar 확장자로 압축/해제 한다.


- 옵션값

  • x : 묶음을 해제
  • c : 파일을 묶음
  • v : 묶음/해제 과정을 화면에 표시
  • z : gunzip을 사용
  • f : 파일 이름을 지정
  • p : 권한(permission)을 원본과 동일하게 유지


ex) tar -cvzf  test.tar.gz [directory]

ex) tar -xvzf test.tar.gz




  • tar
- 일반적으로 tar 명령어와 함께 쓰는 압축/해제 명령어


ex) gzip *
ex) gzip -d *.gz




'System > Linux,Unix' 카테고리의 다른 글

AWK & SED  (0) 2018.08.07
VI 편집기 명령어 정리  (0) 2018.08.07
Unix의 구조 ( Kernel, Shell)  (0) 2018.08.03
Unix와 Linux의 차이  (0) 2018.08.03
FreeMemory에 대한 이해  (0) 2018.07.17

설치


- Docker는 맥에서 무료로 사용 가능하다.

- MacOS의 버전이 Mac OS Yosemite 10.10.3 이상이 필요하다. 이전 버전일 경우 Docker ToolBox를 이용해야한다.

- Docker for Mac에서 설치가능. 아래 링크 확인




https://docs.docker.com/docker-for-mac/install/










설치 확인


$ docker version


or


$ docker run hello-wolrd











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

Docker Network (2) - 브리지(bridge) network  (0) 2018.09.17
Docker Network (1) - docker0  (0) 2018.09.14
Docker Container - 명령어 & Volume  (0) 2018.09.09
Docker Engine, image  (0) 2018.09.08
Docker?  (0) 2018.09.08


Command


Redis Client Too인 rdm이나,  CLI에서 관련 명령어를 수행하려면 https://redis.io/commands 에서 확인해보자.



ex)  저장된 키 값을 모두 지울 때 flushall

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

Single Thread  (0) 2018.11.17
SpirngBoot에서 Redis 연동(Jedis)  (0) 2018.08.09
Redis Pub/Sub Model  (0) 2018.07.01
Java에서 Redis 연동 테스트 (jedis)  (0) 2018.07.01
MacOS에서 Redis 설치 및 실행  (0) 2018.07.01

Netty Base Http Client example Code





NettyHttpClient


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
50
51
52
53
54
 
public class NettyClient {
 
    ChannelFuture cf;
    EventLoopGroup group;
    
    public void connect(String host, int port) {
 
       group = new NioEventLoopGroup();
 
        try {
            Bootstrap b = new Bootstrap();
            b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true)
                    .handler(new NettyHttpChannelInit(group));
 
            cf = b.connect(host, port).sync();
//            cf.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
//post Request Encoder : attribute를 지정하고 싶다면, PostRquestEncoder를 통해 요청해야한다.
    public void createRequest(String host, int port, String url) throws Exception {
        
        
            HttpRequest request = null;
            HttpPostRequestEncoder postRequestEncoder = null;
            
            request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/create"
//                    ,Unpooled.copiedBuffer(url.getBytes(CharsetUtil.UTF_8))
            );
            request.headers().set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_X_WWW_FORM_URLENCODED);
            request.headers().set(HttpHeaderNames.HOST, host+":"+port);
            request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
//            request.headers().set(HttpHeaderNames.CONTENT_LENGTH, url.length());
            
            postRequestEncoder = new HttpPostRequestEncoder(request, false);
            postRequestEncoder.addBodyAttribute("url", url);
            request=postRequestEncoder.finalizeRequest();
            postRequestEncoder.close();
//            cf.channel().writeAndFlush(request).addListener(ChannelFutureListener.CLOSE);
            cf.channel().writeAndFlush(request);
//            System.out.println(request.toString());
    }
    
    public void close() {
        cf.channel().close();
        group.shutdownGracefully();
    }
    
    
}
 
 

cs



-> 가장 중요한 부분은 Request Format이다.  DefaultFullHttpRequest객체를 통해 http의 header, body를 직접 정의할 수 있다.

체크해야할 부분이 있다면, PostRequestEncoder. Post방식의 경우 요청 파라미터가 Url에 명시되지 않기 때문에, PostRequestEncoder를 통해 지정가능하다.








Channelinitializer 



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
 
public class NettyHttpChannelInit extends ChannelInitializer<SocketChannel>{
    
    private boolean ssl = false;
    private EventLoopGroup group;
    
     public NettyHttpChannelInit(EventLoopGroup group) {
         this.group = group;
    }
    @Override
    protected void initChannel(SocketChannel sc) throws Exception {
        // TODO Auto-generated method stub
        
        ChannelPipeline p = sc.pipeline();
        if(ssl) {
            SslContext sslCtx = null;
            try {
                sslCtx = SslContextBuilder.forClient()
                        .trustManager(InsecureTrustManagerFactory.INSTANCE).build();
                 p.addLast(sslCtx.newHandler(sc.alloc()));
            } catch (SSLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    
        /**
         *
         * Message Decoder, FastLz...
        */
    
    //    p.addLast(new MessageDecoder());
 
        
        //chunked 된 응답을 집계하는 코덱
        p.addLast("chunked",new HttpObjectAggregator(1048576));
        p.addLast("codec",new HttpClientCodec());
        p.addLast(new NettyHttpHandler(group, sc));
    }
}
cs



-> 채널을 초기화하는 객체에서는 서버에서 데이터를  받기 위해 여러 핸들러를 정의했다. 

샘플 코드에서는 4개의 핸들러를 추가었다.



1) sslCtx.newHandler : SSL,TLS 성립된 서버와의 통신을 위해 추가된 코덱 (https에 해당한다.)


2)HttpObjectAggregator : chunked된 응답을 집계하는 코덱이다.



* Chunked

  - Chunk Response, "덩어리 응답" 전체 페이지를 가공하지 않는다.

  - 서버측에서 html 전부 생성한 후에 클라이언트에게 보내는 것이 아니라 html 덩어리(chunk) 단위로 쪼개서 보낼  있다.

  - 브라우저(클라이언트)에게 전체 컨텐츠 크기가 얼마나 큰지 알려주지 않아도된다는 특징이 있다. 

  - 따라서동적인 크기의 컨텐츠  스트리밍에 적합하고 Chunked transfer encoding 사용해야하며 netty의 경우 httpObjectAggregator 코덱에 해당된다.

 

3) httpClientCodec


송신시에는 HttpClientCodec을 사용해야 하며. HttpResponseEncoder로 대신 사용할 수 있다.

pipeline.addLast("encoder", new HttpClientCodec());

pipeline.addLast("encoder", new HttpResponseEncoder());


수신시에는 HttpServerCodec 사용해야 하며아래와 같이 HttpRequestDecoder대신 사용할 수 있다.

pipeline.addLast("decoder", new HttpServerCodec());

pipeline.addLast("decoder", new HttpRequestDecoder());

 


4) NettyHttpHandler : 사용자 정의 핸들러, SimpleChannelInboundHandler를 상속받은 사용자 정의 객체 입니다. 실제 메시지를 확인하기 위해 만들었다.





NettyClientHandler


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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
 
 
public class NettyHttpHandler extends SimpleChannelInboundHandler<HttpObject> {
 
    private EventLoopGroup group;
    private SocketChannel sc;
    private int count=0;
    
 
    public NettyHttpHandler(EventLoopGroup group, SocketChannel sc) {
        this.group = group;
        this.sc =sc;
    }
 
 
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelActive(ctx);
//        System.out.println("connect:"+ctx.channel().isActive());
    }
    
 
 
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
        // TODO Auto-generated method stub
//        System.err.println(msg);
        
        if (msg instanceof HttpResponse) {
            HttpResponse response = (HttpResponse) msg;
            
            
            System.err.println("STATUS: " + response.status());
            System.err.println("VERSION: " + response.protocolVersion());
            
 
            if (!response.headers().isEmpty()) {
                for (CharSequence name : response.headers().names()) {
                    for (CharSequence value : response.headers().getAll(name)) {
                        System.err.println("HEADER: " + name + " = " + value);
                    }
                }
                System.err.println();
            }
 
            if (HttpUtil.isTransferEncodingChunked(response)) {
                System.err.println("CHUNKED CONTENT {");
            } else {
                System.err.println("CONTENT {");
            }
        }
        if (msg instanceof HttpContent) {
            count++;
            HttpContent content = (HttpContent) msg;
            System.err.println(count+". create url = "+content.content().toString(CharsetUtil.UTF_8));
            System.err.flush();
 
            if (content instanceof LastHttpContent) {
                System.err.println("} END OF CONTENT");
            }
        }
    }
 
        
 
 
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        cause.printStackTrace();
        ctx.close();
        sc.close();
        group.shutdownGracefully();
    }
cs





구조




Kernel 


- 운영체제의 일부분으로 운영체제의 핵심을 이룬다.

- 커널은 컴퓨터 부팅 시 메모리에 적재되며 시스템이 꺼질 때 까지 실행한다. 

- 대부분 C로 작성 되었지만, 일부분 효율성을 고려하여 어셈블리언어로 작성되었다.

- System call 인터페이스를 통해 커널을 사용한다.



Kernel 의 기능


:시스템에 존재하는 시스템 자원 관리 


 1) 메모리 관리

 2) 프로세스 관리

 3) 파일관리

 4) 입출력관리

 5) 프로세스간 상호 통신





Shell





-  하나의 프로그램, 사용자가 처음 로그인 성공하면 커널이 최초로 사용자에게 할당해주는 프로그램이다.

-  쉘은 운영체제의 커널과 사용자 사이의 인터페이스 역할

-  사용자가 터미널에서 입력한 명령어는 쉘에 의해 타당성 여부를 검증 

-  간단히 정의하면, 명령어 번역기 프로그램이다.




Shell의 종류


-  쉘에는 Bourne shell, korn shell, cShell이 있다.

-  Bourne Shell과 Korn Shell의 프롬프트는 $ 이며, cShell은 %이다.


- 흔히 말하는 bash는 Bourne Again Shell의 축약어이다.





메타 문자


쉘에는 메타 문자라는 것이 존재하는데 어떤 문자들을 특수하게 처리하게 해주며 명령의 편의를 돕는다.





>

 표준출력을 파일에 기록하는 출력 

 >>

 표준출력을 파일 끝에 덧붙이는 출력

 <

 파일로부터 표준 입력을 읽는 입력

 <<EOF

 EOF문자를 만나면 표준 입력이 끝남

 *

 0개 이상의 문자와 일치하는 파일 치환

 ?

 1개의 문자와 일치하는 파일 치환

 | 

 어떤 프로세스의 출력을 다른 프로세스의 입력으로 보내는 파이프 기호

 ; 

 명령어 종결

 ||

 이전명령 실패하면 뒤의 명령 실행

 && 이전 명령 성공해야만 뒤의 명령 실행
 & 백그라운드 실행
 # 주석
 $ 변수의 값
 \ 뒤에 나오는 메타문자를 일반문자로 해석




'System > Linux,Unix' 카테고리의 다른 글

VI 편집기 명령어 정리  (0) 2018.08.07
명령어 정리  (0) 2018.08.07
Unix와 Linux의 차이  (0) 2018.08.03
FreeMemory에 대한 이해  (0) 2018.07.17
vi/vim 에서 문자 일괄 변경  (1) 2018.07.17

+ Recent posts