메모 목적의 글입니다.

19년 9월 기준으로 기존에 자주 사용하던 apache http 컴포넌트에서는 http 2를 정식으로 지원하지 않는 것 같음
현재 개발 기술 스택인 java+spring 환경에서, 애플 APNS와 통신시 http 2로 통신해야해서 통신 모듈을 변경함(java도 가능하면 11로 올리세요. 8에서는 문제 있음)


  1. okhttp 디펜더시 추가
        <dependency>
               <groupId>com.squareup.okhttp3</groupId>
               <artifactId>okhttp</artifactId>
               <version>4.1.0</version>
          </dependency>

  1. Spring restTemplate에 셋팅
     
    private RestTemplate restTemplate = new RestTemplate();
     
     @PostConstruct //init 시점 및 방법은 선호하는 방법에 따라서 셋팅
     private void init() {
          // @formatter:off
          OkHttpClient client = new OkHttpClient.Builder()
               .readTimeout(5, TimeUnit.SECONDS)
               .connectTimeout(7, TimeUnit.SECONDS)
               .connectionPool(new ConnectionPool(30, 10, TimeUnit.MINUTES)) //커넥션풀 적용
               .build();
          // @formatter:on
          OkHttp3ClientHttpRequestFactory crf = new OkHttp3ClientHttpRequestFactory(client);
          restTemplate.setRequestFactory(crf);
     }


  1. 사용하는 소스 예(일부분)

               HttpHeaders headers = new HttpHeaders();
               headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
               //ex) Bearer test.test.test
               headers.set("Authorization", authorization);
               headers.set("apns-id", apnsId); //A canonical UUID that identifies the notification. example UUID is as follows:123e4567-e89b-12d3-a456-42665544000
              
             //If the value is 0, APNs treats the notification as if it expires immediately and does not store the notification or attempt to redeliver it.
               headers.set("apns-expiration", "0");
               headers.set("apns-priority", "10"); //The priority of the notification. 10은 즉시, 5는 배터리상태 고려해서 발송
               headers.set("apns-topic", apnsTopic);
               log.debug("IOS APNS푸시 요청headers\n{}", headers);
              
             Map<String, Object> bodyMap = new HashMap<String, Object>();
               bodyMap.put("aps", aPNSPayloadAPS);
               String bodyJson = OM.writeValueAsString(bodyMap);
               log.debug("IOS APNS푸시 요청bodyJson\n{}", bodyJson);
               
            //http 200 응답이면 API요청 성공
               ResponseEntity<String> rslt = restTemplate.exchange(apiURL, HttpMethod.POST, new HttpEntity<String>(bodyJson, headers), String.class);
               log.debug("IOS APNS 푸시발송 요청 리턴 결과\n{}", rslt);


메모

- MSA 아키텍쳐, 그 중에 outbox pattern

  ( RDB 트랜잭션을 이용한 atomiccally 처리)


https://microservices.io/patterns/data/transactional-outbox.html


intellij에서 builder 등을 포맷터 적용시 줄 바꿈에 대해서 wrap처리(Chained mehtod calls 'Wrap')


  1. Settings -> Editor -> Code Style -> Java메뉴
  2. Wrapping and Braces 탭에서 ChainedMethod calls 부분 설정 변경


  1. 샘플소스( //@formatter:off 처리를 할 필요가 없음)


  • 주의
    • 해당 설정은 개인 프로젝트의 디렉토리 경로 등에 디펜더시되어 있으며, 서비스 환경에서 로그 출력시 성능이 저하될 수 있으니 개발 환경에서 디버깅 용으로만 사용

  1. maven 라이브러리 추가
        <!-- sql로그를 남기기 위한 라이브러리 -->
        <dependency>
               <groupId>org.bgee.log4jdbc-log4j2</groupId>
                <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
               <version>1.16</version>
          </dependency>

  1. jdbc driverClassName을 "net.sf.log4jdbc.sql.jdbcapi.DriverSpy"로 변경
  2. resources 디렉토리에 "log4jdbc.log4j2.properties" 파일 추가 후 아래 내용 작성
log4jdbc.spylogdelegator.name =  net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
#sql문을 최대 몇 라인까지 출력할지 여부: 0은 제한 없음
log4jdbc.dump.sql.maxlinelength=0

  1. logback  설정에 출력 및 미출력할 로그 어펜더 정의(샘플)
<logger name="jdbc" level="OFF"/>
    <logger name="jdbc.audit" level="OFF"/>
    <logger name="jdbc.connection" level="OFF"/>
    
    <!-- SQL문과 해당 SQL을 실행시키는데 수행된 시간  정보(milliseconds)를 포함한다. -->  
    <logger name="jdbc.sqltiming" additivity="false">
        <level value="DEBUG" />
        <appender-ref ref="CONSOLE" />
    </logger>
    
      <!-- SQL 결과 조회된 데이터의 table을 로그로 남긴다 -->
     <logger name="jdbc.resultsettable" additivity="false">
        <level value="DEBUG" />
        <appender-ref ref="CONSOLE" />
    </logger>
    
        <!-- SQL문만을 로그로 남기며, PreparedStatement일 경우  관련된 argument 값으로 대체된 SQL문이 보여진다 -->
<!--      <logger name="jdbc.sqlonly" additivity="false">  -->
<!--         <level value="DEBUG" /> -->
<!--         <appender-ref ref="CONSOLE" /> -->
<!--     </logger> -->
    <!-- ResultSet을 포함한 모든 JDBC 호출 정보를 로그로 남기므로  매우 방대한 양의 로그가 생성된다 -->
<!--      <logger name="jdbc.resultset" additivity="false">  -->
<!--         <level value="DEBUG" /> -->
<!--         <appender-ref ref="CONSOLE" /> -->
<!--     </logger> -->


intellij에서 maven을 사용할 때 어떤 dependencies인지 검색하고 싶을 때

  1. 우측의 Maven선택
  2. Dependencies 선택
  3. 찾고 싶은 라이브러리 타이핑
    1. 예를 들어 okhttp 어떤 버전을 사용하는지 궁금할 때 'okhttp'로 타이핑하면 필터링 됨
  4. 기타
    1. 플러그인 중에 diagram을 볼 수 있는 것도 존재함




몽고DB replica 재 설정방법 샘플
- primary에 커맨드 접속
- repl_set이라는 replica에 대해서 가중치를 포함하여 reconfig를 실행함
- 순단 발생하니 주의

-- config 재 정의
config = {
    "_id" : "repl_set",    
    "members" : [
            {
                    "_id" : 0,
                    "host" : "primary서버의 IP입력:27017",
                    "priority" : 3
            },
            {
                    "_id" : 1,
                    "host" : "secondary서버의 IP입력:27017",
                    "priority" : 2
            },
            {
                    "_id" : 2,
                    "host" : "arbiter서버의 IP입력:27017",                    
                    "arbiterOnly" : true
            }
    ]
}


-- re config 실행
rs.reconfig(config,  {force : true} );

-- 잘 저장되는지 테스트
use testdb
db.test_collection.insert({'msg':'test message'})
db.test_collection.find()



-- 참고: 최초 replica 설정일 경우 rs.initiate() 후 셋팅 필요

config = {
    "_id" : "repl_set",    
    "members" : [
            {
                    "_id" : 0,
                    "host" : "primary서버의 IP입력:27017",
                    "priority" : 3
            },
            {
                    "_id" : 1,
                    "host" : "secondary서버의 IP입력:27017",
                    "priority" : 2
            },
            {
                    "_id" : 2,
                    "host" : "arbiter서버의 IP입력:27017",                    
                    "arbiterOnly" : true
            }
    ]
}


rs.initiate(config);


  1. EPEL 저장소 추가
sudo yum install epel-release
sudo yum update

  1. Install Redis
sudo yum install redis

  1. Start Redis
sudo systemctl start redis

#버전확인
redis-cli -v

  1. 재 부팅시 자동으로 시작되도록 처리
sudo systemctl enable redis

#확인
systemctl list-unit-files | grep redis

  1. 추가로 redis conf 튜닝 예
Redis Conf 튜닝 예(sudo vim /etc/redis.conf)

#방화벽으로 관리할 경우라서 편의성 문제로 모든 IP에서 접근 허용
bind 0.0.0.0

#주석처리(메모리 캐쉬로만 사용하기 위해서)
#save 900 1
#save 300 10
#save 60 10000


537라인쯤에 아래 추가
maxmemory 256m


적용 : sudo systemctl restart redis



다른 디렉토리에서 명령어 실행하는 실수를 막고 캡쳐 등을 할때 현재 시간을 알 수 있기 위해서 변경해서 사용

변경 명령어 (sudo로 실행)
sudo su
echo 'PS1="[\u@\h \$PWD \D{%T}]\\$ "' >> /etc/bashrc && source /etc/bashrc


+ Recent posts