rabbitMQ server 설치 및 플러그인 화면 확인

 

CentsOS 7.x

* 서버는 무조건 알랭을 설치 (erlang)

 

참고

https://marshallslee.tistory.com/entry/CentOS-7%EC%97%90-RabbitMQ-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0

https://babtingdev.tistory.com/340

 

1. 패키지 업데이트

yum install epel-release

yum update

reboot

 

2. erlang 설치

wget http://packages.erlang-solutions.com/erlang-solutions-1.0-1.noarch.rpm

rpm -Uvh erlang-solutions-1.0-1.noarch.rpm

yum install erlang

 

 

3. 설치 패키지 확인

https://packagecloud.io/rabbitmq/rabbitmq-server/

rpm -Uvh https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.7.12/rabbitmq-server-3.7.12-1.el7.noarch.rpm

 

rpm -Uvh https://packagecloud.io/rabbitmq/rabbitmq-server/packages/el/7/rabbitmq-server-3.7.23-1.el7.noarch.rpm

  • 최신

rpm -Uvh https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.8.2/rabbitmq-server-3.8.2-1.el7.noarch.rpm

 

  • 경고 잡기

[root@localhost ~]# rpm --import https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey

[root@localhost ~]# rpm --import https://packagecloud.io/gpg.key

[root@localhost ~]# rpm --import https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc

[root@localhost ~]# rpm -Uvh https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.8.2/rabbitmq-server-3.8.2-1.el7.noarch.rpm

 

  • 설치 에러 확인

Failed dependencies:

        socat is needed by rabbitmq-server-3.8.2-1.el7.noarch

    rabbitMq를 설치하는데 socat이 필요하다고 에러가 나는 경우 socat 설치

yum install socat

 

4. 모니터링 플러그인

rabbitmq-plugins enable rabbitmq_management

chown -R rabbitmq:rabbitmq /var/lib/rabbitmq/

 

5. 방화벽

firewall-cmd --permanent --zone=public --add-port=4369/tcp

firewall-cmd --permanent --zone=public --add-port=5671/tcp

firewall-cmd --permanent --zone=public --add-port=5672/tcp

firewall-cmd --permanent --zone=public --add-port=15672/tcp

firewall-cmd --permanent --zone=public --add-port=25672/tcp

firewall-cmd --permanent --zone=public --add-port=61613/tcp

firewall-cmd --permanent --zone=public --add-port=61614/tcp

firewall-cmd --permanent --zone=public --add-port=1883/tcp

firewall-cmd --permanent --zone=public --add-port=8883/tcp

 

firewall-cmd --reload

 

6-1. 서비스 등록

systemctl enable rabbitmq-server

 

6-2. 서비스 시작

systemctl start rabbitmq-server

 

7. 사용자 등록

 

계정 추가 (admin 계정 test/test 계정

rabbitmqctl add_user 계정 패스워드

rabbitmqctl add_user admin 1234

 

계정을 관리자로 등록

rabbitmqctl set_user_tags 계정 administrator

rabbitmqctl set_user_tags admin administrator

 

권한 설정

rabbitmqctl set_permissions -p / 계정".*" ".*" ".*"

rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"

 

8. 상태확인

rabbitmqctl status

 

systemctl restart rabbitmq-server

 

- 화면확인

http://192.168.5.114:15672/

 

 

9. 운영

 

  •  설정

https://www.rabbitmq.com/configure.html 

https://www.rabbitmq.com/configure.html#config-file-formats

 

중요 설정

RabbitMQ가 데이터를 저장하는 파티션의 디스크 여유 공간 제한.

heartbeat = 60

 

 

지도 표기 사이트들


윈디


어스널

 

 

이전글 : 네이버 뉴스 RSS 읽어 오기 -1-

 

네이버 뉴스 RSS 읽어 오기 -1-

개인 목적으로 RSS 읽어오는 것은 불법이 아니지만 홈페이지나 개인 블로그에 개재하는 것은 불법 및 저작권 위반일수 있으니 이는 확인 하시기 바랍니다. jsp 자바 웹서비스에서 RSS 읽어 보여주는 테스트를 진행..

torrms.tistory.com

 

먼저, 메이븐이나 다른 라이브러리는 읽지 않아도 되었지만, 혹여 컴파일이 안되시는 경우가 있을 수 있으니

import  부분을 잘 참고 하시기 바랍니다.

 

자 파싱을 하도록합니다.

기본 파싱 소스는 

https://www.vogella.com/tutorials/RSSFeed/article.html

 

RSS feeds with Java - Tutorial

Lars Vogel (c) 2008, 2016 vogella GmbH Version 2.2, 26.09.2016 RSS Feeds with Java. This tutorial explains how to read and create RSS feeds with Java. It uses the Stax XML API. Eclipse is used as the Java IDE and Java7 is used.

www.vogella.com

참조 하였습니다. 좋은 형태이고 저는 살짝 정리를 하였습니다.

다만, 네이버 쪽이라든지 다른 형태의 구성이 약간 상의한 부분이 있어 수정을 했습니다.

전체 소스는 아래 있습니다.

 

RSSFeedParser.java

 

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.XMLEvent;

import 앞전소스들.Feed;
import 앞전소스들.FeedMessage;

/**
 * @author torrms
 *
 */
public class RSSFeedParser {
	static final String TITLE = "title";
    static final String DESCRIPTION = "description";
    static final String LANGUAGE = "language";
    static final String LINK = "link";
    static final String AUTHOR = "author";
    static final String ITEM = "item";
    static final String LAST_BUILD_DATE = "lastBuildDate";
    
    //message
    static final String PUB_DATE = "pubDate";
    static final String CATEGORY = "category";
    static final String THUMBNAIL = "thumbnail";
    
    
    final URL url;
    
    public RSSFeedParser(String feedUrl) {
        try {
            this.url = new URL(feedUrl);
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
    }
    
    public Feed readFeed() {
        Feed feed = null;
        try {
            boolean isFeedHeader = true;
            // Set header values intial to the empty string
            String description = "";
            String title = "";
            String link = "";
            String language = "";
            String author = "";
            String lastBuildDate = "";
            String category = "";
            String pubDate = "";
            String thumbnail = "";

            // First create a new XMLInputFactory
            XMLInputFactory inputFactory = XMLInputFactory.newInstance();
            // Setup a new eventReader
            InputStream in = read3();
            
            XMLEventReader eventReader = inputFactory.createXMLEventReader(in);
            // read the XML document
            while (eventReader.hasNext()) {
            	
                XMLEvent event = eventReader.nextEvent();
                
                if (event.isStartElement()) {
                    String localPart = event.asStartElement().getName()
                            .getLocalPart();
                    switch (localPart) {
                    case ITEM:
                        if (isFeedHeader) {
                            isFeedHeader = false;
                            feed = new Feed(title, link, description, language,lastBuildDate);
                        }
                        event = eventReader.nextEvent();
                        break;
                    case TITLE:
                    	
                        title = getCharacterData(event, eventReader);
                        break;
                    case DESCRIPTION:
                        description = getCharacterData(event, eventReader);
                        break;
                    case LINK:
                        link = getCharacterData(event, eventReader);
                        break;
                    case LANGUAGE:
                        language = getCharacterData(event, eventReader);
                        break;
                    case AUTHOR:
                        author = getCharacterData(event, eventReader);
                        break;
                    case LAST_BUILD_DATE:
                    	lastBuildDate = getCharacterData(event, eventReader);
                        break;
	                case PUB_DATE:
	                	pubDate = getCharacterData(event, eventReader);
	                	break;
	                case CATEGORY:
	                	category = getCharacterData(event, eventReader);
	                	break;
	                case THUMBNAIL:
	                	thumbnail = getCharacterData(event, eventReader);
	                	// ex ) <media:thumbnail url="https://imgnews.pstatic.net/image/thumb140/5551/2019/09/04/60286.jpg"/> 형태이므로
	                	@SuppressWarnings("unchecked") Iterator<Attribute> attribue = event.asStartElement().getAttributes();
	                    while(attribue.hasNext()){
	                        Attribute myAttribute = attribue.next();
	                        if(myAttribute.getName().toString().equals("url")){
	                            thumbnail = myAttribute.getValue();
	                        }
	                    }
	                	break;
	                default: 
	                	//System.out.println("localPart:"+ localPart);
	                	break;
	                }
                    
                    
                } else if (event.isEndElement()) {
                    if (event.asEndElement().getName().getLocalPart() == (ITEM)) {
                        FeedMessage message = new FeedMessage();
                        
                        message.setAuthor(author);
                        message.setDescription(description);
                        message.setLink(link);
                        message.setTitle(title);
                        message.setCategory(category);
                        message.setPubdate(pubDate);
                        message.setThumbnail(thumbnail);
                        
                        feed.getMessages().add(message);
                        event = eventReader.nextEvent();
                        continue;
                    }
                }
            }
        } catch (XMLStreamException e) {
            throw new RuntimeException(e);
        }
        return feed;
    }
    
    
    private String getCharacterData(XMLEvent event, XMLEventReader eventReader)
            throws XMLStreamException {
        String result = "";
        event = eventReader.nextEvent();
        if (event instanceof Characters) {
            result = event.asCharacters().getData();
        }
        return result;
    }

//    기존 리더
//    private InputStream read() {
//        try {
//        	return url.openStream();
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
//    }
   
    private InputStream read3() {
        try {
        	ReplacingInputStream  ris = new ReplacingInputStream(url.openStream(), "&apos;", "'");
        	return ris;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static InputStream byteArrayToInputStream(byte[] srcBytes) {
        return new ByteArrayInputStream(srcBytes);
    }
    
}

 

기존의 리더리를 통해 읽어서 테스트를 진행 하도록 했습니다. 

정보는 정리가 되어 잘 오고 있었습니다. 그런데...

 

원정보

...

<title>'미드 체르노빌....' XXXX </title> 

...

 

출력정보

...

title = '

...

그렇습니다. 기존의 단순  url.openStream 으로 InputStream 으로는 따옴표가 읽혀 지지 않습니다.

작은 따옴표(싱글 퀘테이션) 등이 말썽으로 원천의 스트림을 출력해보면 

&apos;미드 체르노빌 ...

위와 같이 읽어 오는 것이 바로 치환이 되버려서 오는 겁니다.

짜증이... 변환이 필요합니다. replace 처럼요... 물론 replace를 쓸수는 없습니다. 스트림이니까요

 

외국에 깃 양반을 검색합니다. .... 검색중... 그렇습니다. 전 할 줄 모르고 구글이 해줍니다. ^^;

마침네. simon 이란 시몬이란 양반이 만들어 놓은게 있습니다. 데려옵니다.

 

두둥, ReplacingInputStream 클래스가 바로 그것입니다. 

ReplacingInputStream .java

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;

/**
 * Created by simon on 8/29/17.
 */
public class ReplacingInputStream extends FilterInputStream {

    private Queue<Integer> inQueue, outQueue;
    private final byte[] search, replacement;

    public ReplacingInputStream(InputStream in, String search, String replacement) {
        super(in);

        this.inQueue = new LinkedList<>();
        this.outQueue = new LinkedList<>();

        this.search = search.getBytes();
        this.replacement = replacement.getBytes();
    }

    private boolean isMatchFound() {
        Iterator<Integer> iterator = inQueue.iterator();

        for (byte b : search) {
            if (!iterator.hasNext() || b != iterator.next()) {
                return false;
            }
        }

        return true;
    }

    private void readAhead() throws IOException {
        // Work up some look-ahead.
        while (inQueue.size() < search.length) {
            int next = super.read();
            inQueue.offer(next);

            if (next == -1) {
                break;
            }
        }
    }

    @Override
    public int read() throws IOException {
        // Next byte already determined.

        while (outQueue.isEmpty()) {
            readAhead();

            if (isMatchFound()) {
                for (@SuppressWarnings("unused") byte a : search) {
                    inQueue.remove();
                }

                for (byte b : replacement) {
                    outQueue.offer((int) b);
                }
            } else {
                outQueue.add(inQueue.remove());
            }
        }

        return outQueue.remove();
    }

    @Override
    public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
    }

    // copied straight from InputStream inplementation, just needed to to use `read()` from this class
    @Override
    public int read(byte b[], int off, int len) throws IOException {
        if (b == null) {
            throw new NullPointerException();
        } else if (off < 0 || len < 0 || len > b.length - off) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return 0;
        }

        int c = read();
        if (c == -1) {
            return -1;
        }
        b[off] = (byte)c;

        int i = 1;
        try {
            for (; i < len ; i++) {
                c = read();
                if (c == -1) {
                    break;
                }
                b[off + i] = (byte)c;
            }
        } catch (IOException ee) {
        }
        return i;
    }
}

사랑해 줍니다.

 

그러면 문제가 해결되어 나오게 됩니다. 아~ 테스트 소스도 올립니다.

단, json 이나 여타 다른 정보는 설정이 된 상태에서 합니다. 

따라서 java APP 소스와 컨트롤러( Controller )는 상황에 맞게 하시면 됩니다.

 

JAVA

import 앞전소스.Feed;
import 앞전소스.FeedMessage;

/**
 * @author torrms
 *
 */
public class testRss {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		RSSFeedParser parser = new RSSFeedParser(
                "http://newssearch.naver.com/search.naver?where=rss&query=3D 프린터");
        Feed feed = parser.readFeed();
        System.out.println(feed);
        for (FeedMessage message : feed.getMessages()) {
            System.out.println(message);

        }
	}

}

 

Controller

// 네이버 뉴스 RSS 테스트(웹) /////////////////////////////////////////////////////////////////////////////////////////	
	@RequestMapping(value = "/getNewsRSSAjax.json")
	public ModelAndView getNewPage(@RequestParam Map<String, Object> commandMap) {
		
		ModelAndView mv = new ModelAndView();
    	mv.setViewName("jsonView");
    	
		
		log.info("getNewPage");
		String result = "false";
		
		try {
			String keyword = (String) commandMap.get("keyword");
			String maxcnt = (String) commandMap.get("maxcnt");
			String Url = "http://newssearch.naver.com/search.naver?where=rss&query=" + keyword;
			log.info("Url:" + Url);
			
			RSSFeedParser parser = new RSSFeedParser(Url);
			Feed feed = parser.readFeed();
			feed.getMessages();

			// TODO 방식 고려
			// 메모리 방식으로 변경을 고려해야함 RSS 너무 자주 부르게 되므로 
			List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
			
			int i = 0 ;
			int maxcnt_int = 0;
			
			if (maxcnt != null)
				maxcnt_int = Integer.valueOf(maxcnt)+1;
			
			for (FeedMessage message : feed.getMessages()) {
				i++;
				if (i == maxcnt_int)	
					break; 
				Map<String, Object> obj = new HashMap<String, Object>();

				obj.put("title"        , message.getTitle()          );
				obj.put("link"         , message.getLink()            );
				obj.put("description"  , message.getDescription()     );
				obj.put("pubdate"      , message.getPubdate()         );
				obj.put("author"       , message.getAuthor()          );
				obj.put("category"     , message.getCategory()        );
				obj.put("thumbnail"    , message.getThumbnail()       );
//				System.out.println(message);
//				System.out.println(obj);
				listMap.add(obj);
			}
			mv.addObject("resultList",listMap);
			result = "true";
			
		} catch (NullPointerException e) {
			log.info("NullPointerException :"  + e.toString());
		} catch (Exception e) {
			log.info(e.toString());
		} 
		mv.addObject("result", result);
		return mv  ;
	}
    

WEB 


<div id="RSS">
        </div>
        
<!-- jquery 선언 후-->

 <script type="text/javaScript" >
 // 시작
    $(function(){
        /////////////////////////////////////////////////////////////////////////
        //RSS 가져오기
        $.ajax({
            url:"<c:url value='/getNewsRSSAjax.json' />", //요청할 데이터 경로.
            type: 'GET',
            data:{
            	keyword: "3D 프린터",
            	maxcnt: "5",
                },
            dataType: "json", //요청할 데이터에 타입.
            crossDomain: true,
            success: function (data) { //성공적으로 요청했왔을 때...
                
                console.info(data);
                $.each(data.resultList,function(i, d){
                    var title=d["title"]; //title 키의 값을 가져옵니다.
                    var date=new Date(d["pubdate"]); //뉴스 작성 날짜 객체 생성
                    var img=d["thumbnail"];
                    var dateString = date_to_str(date);
                    $("#RSS").append("<ul style='height:140px;'><li><img src='"+img+"'/></li><li>" + title+ "</li><li>" + dateString+ "</li></ul><br/>" );    
                    
                });

                },
                error: function (response) {
                      console.info(response.status);
                      console.info(response.error);
                  }     // “success: function”에 종료
            }); // $.ajax() 메서드에 종료
            
    </script>            

1차 버전이 완료 되었습니다.

분명 특수문자 및 지속적으로 부르는 문제가 있을 것으로 보입니다.

자 나머지는 운영 및 반영에 있습니다. 즐프 하세요

그럼 이만,

개인 목적으로 RSS 읽어오는 것은 불법이 아니지만 홈페이지나 개인 블로그에 개재하는 것은

불법 및 저작권 위반일수 있으니 이는 확인 하시기 바랍니다.

 

jsp 자바 웹서비스에서 RSS 읽어 보여주는 테스트를 진행했습니다.

 

기존의 RSS 기본 구조가 있으며 이를 토대로 변경 및 변형이 조금씩 이뤄진 상태입니다.

물론 완벽히 지키고 있는 곳도 있습니다.

 

네이버의 경우 RSS 주소 찾기가 수월하지 않습니다.

먼저 주소를 확인합니다.

네이버 뉴스 RSS 주소

먼저, 검색어가 필요하고

뉴스 탭으로 이동하게 되면 우측 하단에 RSS 보기가 나타나게 됩니다.

 

위와 같은 결과를 볼수 있습니다.

자 그럼 살짝 분석을 해보면 됩니다.

구조를 보면 

RSS 하위에 channel 이 가 있고 같은 레벨에 ITEM 들이 즐비하게 있습니다. (50개)

 


웹 프로젝트에서 사용을 해보도록 하겠습니다.

준비는 VO식으로 형태를 잡아줄 Feed.java 와 Item(messag)을 잡을 FeedMessage.java를 준비합니다.

한글 주석은 개인적으로 달아 놓은 것으므로 의미상의 분류를 했으니 참고만 하시기 바랍니다.

 

소스 Feed.java

import java.util.ArrayList;
import java.util.List;

/**
 * 피드 읽어 오기
 * @author torrms
 *
 */
public class Feed {
	
	private String title;          /* FEED 제목    title         */
	private String link;           /* 링크         link          */
	private String description;    /* 설명         description   */
	private String language;       /* 언어         language      */
	private String lastbuilddate;  /* 발생일       lastBuildDate */
	

	final List<FeedMessage> entries = new ArrayList<FeedMessage>();

	public Feed(String title, String link, String description, String language, String lastbuilddate) {
        this.title = title;
        this.link = link;
        this.description = description;
        this.language = language;
        this.lastbuilddate = lastbuilddate;
    }
	
	public List<FeedMessage> getMessages() {
        return entries;
    }

	public String getTitle()        { return this.title;        }  /* GET FEED 제목    title         */
	public String getLink()         { return this.link;         }  /* GET 링크         link          */
	public String getDescription()  { return this.description;  }  /* GET 설명         description   */
	public String getLanguage()     { return this.language;     }  /* GET 언어         language      */
	public String getLastbuilddate(){ return this.lastbuilddate;}  /* GET 발생일       lastBuildDate */

	@Override
    public String toString() {
        return "Feed [ description=" + description
                + ", language=" + language + ", link=" + link + ", lastbuilddate="
                + lastbuilddate + ", title=" + title + "]";
    }
}

FeedMessage.java

 

/**
 * RSS 피드 리딩 테스트
 * @author torrms
 *
 */
public class FeedMessage {
	private String title;        /* 제목         title         */
	private String link;         /* 링크         link          */
	private String description;  /* 내용         description   */
	private String pubdate;      /* 날짜         pubDate       */
	private String author;       /* 저작자       author        */
	private String category;     /* 카테고리     category      */
	private String thumbnail;    /* 쎔네일(URL)  thumbnail     */

	public String getTitle()      { return this.title;      }  /* GET 제목         title         */
	public String getLink()       { return this.link;       }  /* GET 링크         link          */
	public String getDescription(){ return this.description;}  /* GET 내용         description   */
	public String getPubdate()    { return this.pubdate;    }  /* GET 날짜         pubDate       */
	public String getAuthor()     { return this.author;     }  /* GET 저작자       author        */
	public String getCategory()   { return this.category;   }  /* GET 카테고리     category      */
	public String getThumbnail()  { return this.thumbnail;  }  /* GET 쎔네일(URL)  thumbnail     */

	public void setTitle(String title)            { this.title       = title;       }   /* SET 제목         title         */
	public void setLink(String link)              { this.link        = link;        }   /* SET 링크         link          */
	public void setDescription(String description){ this.description = description; }   /* SET 내용         description   */
	public void setPubdate(String pubdate)        { this.pubdate     = pubdate;     }   /* SET 날짜         pubDate       */
	public void setAuthor(String author)          { this.author      = author;      }   /* SET 저작자       author        */
	public void setCategory(String category)      { this.category    = category;    }   /* SET 카테고리     category      */
	public void setThumbnail(String thumbnail)    { this.thumbnail   = thumbnail;   }   /* SET 쎔네일(URL)  thumbnail     */

	public String toString() {
        return "FeedMessage [title=" + title + ", description=" + description
                + ", link=" + link + ", author=" + author + ", pubDate = " + pubdate + ", category=" + category + ", thumbnail=" + thumbnail
                + "]";
    }
}

이렇게 준비하면 기본 준비는 끝납니다.

그럼 이제 파싱을 해서 서비스는 부분을 만들어 보겠습니다.

다음글에 계속이어집니다.

 

요즘 CRUD 커스텀에 열을 올리고 있습니다.

업무 효율도 있지만, 결국 프로그램의 본수 찍어내는 것에 집중 된 작업들이 꽤나 있지요

 

해서, 그 일환으로 작업을 하고 있네요, 그런데...

 

아무리 작업을 진행하려해도 안되는 프로젝트가 나타납니다.

프로젝트 화면

위프로젝트에서  eGovFrame Templates 실행!

실행을 해서 테이블 읽어서 작업을 진행하려고 합니다.

기존에 설계된 TABLE가 존재하고 이를 활용하여 진행되는 만큼 설정과 연결을 확실히 합니다.

 

 

 

그런데 2번을 간과하고 저는 Project Explorer 만 본겁니다. 즉 package Explorer을

순간 됬었다 또는 열기만 하고 된줄 알고 넣었다가 두둥

Pakage Selection 이 안보이는 시원한 사태???

 

 

 

패키지가 안보이는 상황

위 스샷 처럼 패키지 보이지 않는 상태가 된다. 

아래 확인 사항을 반드시 처리하고 진행하자

 

※ 확인사항


1. Database Source Explorer 에 연결이 되어 있는가?

 

2. Package Explorer 창을 열었는가?                                        (단순 열기이 아니라 F5 및 아래로 열어 확인함)


 

+ Recent posts