1. ejabberd 서버설치
RPM 패키지로 설치
참고: https://www.process-one.net/en/ejabberd/downloads/ 사이트에서 RPM 패키지 URL확인 가능

예)
wget 'https://www.process-one.net/downloads/downloads-action.php?file=/ejabberd/19.09.1/ejabberd-19.09.1-0.x86_64.rpm' -O ejabberd.rpm
rpm -ivh ejabberd.rpm


#서비스로 시작하기 위해서 복사
cp /opt/ejabberd-18.12.1/bin/ejabberd.service /etc/systemd/system/

#systemctl enable(서버 재 시작시 ejabberd도 시작됨)
systemctl enable ejabberd

#서비스 시작
systemctl start ejabberd

#확인
systemctl status ejabberd

  1. 설치된 서버 확인
    1. 리슨포트 확인
      1. netstat -anp | grep 'LISTEN' 명령어로 확인
        1. 5222포트는 메신저용, 5280은 admin web용


  2. 자주 쓰는 명령어
cd /opt/ejabberd-19.09.1/bin 후(설치한 버전에 따라서 다름)


-- 등록된 계정 리스트 조회
./ejabberdctl registered_users 호스트(ex. localhost)


-- 신규 계정 등록
./ejabberdctl register ID입력 서버 호스트(ex. localhost) 암호


-- 설정변경(ex. admin 계정)
vi /opt/ejabberd/conf/ejabberd.yml



아는 사람은 모두 알겠지만 Elasticsearch쪽이 클라우드가 기여 안하고 사용만한다고(돈벌어간다고 ㅎㅎ)해서 라이센스 일부를 변경함(ex. AWS가 fork 해서 'Open Distro for Elasticsearch' 만듬)



Elasticsearch 6.3버전부터는 x-pack code가 Elastic License하에 배포되고 있으니 회사에서 사용하려면 라이센스 계약을 해야함


x-pack feature를 사용하지 않는다면, 해당 코드를 제외하고 설치해야함



혹, 잘못된게 있으면 댓글 달아주세요.

'ElasticSearch > ElasticSearch' 카테고리의 다른 글

Elasticsearch Performance Tuning  (0) 2021.03.08
import java.util.Properties;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.URLName;
import javax.mail.search.FlagTerm;
/**
 * IMAP 이메일을 가져오는 샘플 소스
 *  - 주의: 간단히 POC한 소스라서 예외처리 및 부가처리는 완벽히 안되어 있음
 *
 * @author 엄승하
 */
public class IMAPEmailGetSample {
     public static void main(String[] args) throws Exception {
          System.out.println("-- IMAP Emal 가져오기: Start\n\n");
          String host = "입력필요"; //imap 호스트 주소. ex) imap.gmail.com
          String userEmail = "입력필요"; //유저 이메일 주소
          String password = "입력필요"; //유저 암호
          IMAPMailService mailService = new IMAPMailService();
          mailService.login(host, userEmail, password);
          int messageCount = mailService.getMessageCount();
          //테스트 목적이라서 5개 초과이면 5개만 처리: TODO 삭제
          if (messageCount > 5) {
               messageCount = 5;
          }
          Message[] msgArray = mailService.getMessages(false);
          for (int i = 0; i < messageCount; i++) {
               Message msg = msgArray[i];
               if (msg.getSubject() != null) {
                    System.out.println(String.format("컨텐츠타임: %s", msg.getContentType()));
                    System.out.println(String.format("발신자[0]: %s", msg.getFrom()[0]));
                    System.out.println(String.format("메일제목: %s", msg.getSubject()));
                    String mailText = mailService.getEmalText(msg.getContent());
                    System.out.println(String.format("메일내용: %s", mailText));
               }
          }
          mailService.logout(); //로그아웃
          System.out.println("\n\n-- IMAP Emal 가져오기: 종료");
     }
}
/**
 * IMAP 관리 inner클래스
 *  - 참고: https://javapapers.com/java/receive-email-in-java-using-javamail-gmail-imap-example/
 * 
 * @author 엄승하
 */
class IMAPMailService {
     private Session session;
     private Store store;
     private Folder folder;
     // hardcoding protocol and the folder
     // it can be parameterized and enhanced as required
     private String protocol = "imaps";
     private String file = "INBOX";
     public IMAPMailService() {
     }
     public boolean isLoggedIn() {
          return store.isConnected();
     }
     /**
      * 메일 본문 텍스트 내용을 가져옴
      *
      * @param content
      * @return
      * @throws Exception
      */
     public String getEmalText(Object content) throws Exception {
          //TODO: 개발 필요
          System.out.println("####  컨텐츠 타입에 따라서 text body 또는 멀티파트 처리 기능 구현이 필요");
          if (content instanceof Multipart) {
               System.out.println("Multipart 이메일임");
          } else {
               System.out.println(content);
          }
          return null;
     }
     /**
      * to login to the mail host server
      */
     public void login(String host, String username, String password) throws Exception {
          URLName url = new URLName(protocol, host, 993, file, username, password);
          if (session == null) {
               Properties props = null;
               try {
                    props = System.getProperties();
               } catch (SecurityException sex) {
                    props = new Properties();
               }
               session = Session.getInstance(props, null);
          }
          store = session.getStore(url);
          store.connect();
          folder = store.getFolder("inbox"); //inbox는 받은 메일함을 의미
          //folder.open(Folder.READ_WRITE);
          folder.open(Folder.READ_ONLY); //읽기 전용
     }
     /**
      * to logout from the mail host server
      */
     public void logout() throws MessagingException {
          folder.close(false);
          store.close();
          store = null;
          session = null;
     }
     public int getMessageCount() {
          //TODO: 안 읽은 메일의 건수만 조회하는 기능 추가
          int messageCount = 0;
          try {
               messageCount = folder.getMessageCount();
          } catch (MessagingException me) {
               me.printStackTrace();
          }
          return messageCount;
     }
     /**
      * 이메일 리스트를 가져옴
      *
      * @param onlyNotRead 안읽은 메일 리스트만 가져올지 여부
      * @return
      * @throws MessagingException
      */
     public Message[] getMessages(boolean onlyNotRead) throws MessagingException {
          if (onlyNotRead) {
               return folder.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false));
          } else {
               return folder.getMessages();
          }
     }
}

  1. open jdk 11을 우선 설치
  2. Preferences -> Java -> Installed JREs에서 jdk 11을 추가


  1. 프로젝트의 'Properties'의 Java Compiler 및 Java BUild Path-> Libraries에 java 11셋팅

메모 목적의 글입니다.

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> -->


+ Recent posts