2017년 12월 11일 월요일

AngularJS & Angular의 url에서 hashtag(#) 제거

  • AngularJS인 경우 설정 (** html에 <base href="/"> 추가)

1
2
3
angular.config(['$locationProvider'], function ($locationProvider) {
    $locationProvider.html5Mode(true);
});
  • Angular인 경우 설정 (** html에 <base href="/"> 추가)

1
2
3
4
5
6
@NgModule({
    imports: [
        RouterModule.forRoot(LAYOUT_ROUTES, { useHash: false })
    ],
    ...
})
  • UrlRewriteFilter 설정 (Spring Framework, Gradle)

    • 의존성 설정
compile("org.tuckey:urlrewritefilter:${urlrewritefilter_version}")
    • Custom UrlRewriteFilter 생성 (url-rewrite.xml 위치를 변경을 위해)
 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
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tuckey.web.filters.urlrewrite.Conf;
import org.tuckey.web.filters.urlrewrite.utils.StringUtils;

import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import java.io.InputStream;
import java.net.URL;

/**
 * Subclass of {@link org.tuckey.web.filters.urlrewrite.UrlRewriteFilter}
 * that overrides the configuration file loading mechanism.
 */
public class UrlRewriteFilter extends org.tuckey.web.filters.urlrewrite.UrlRewriteFilter {

    private final Logger log = LoggerFactory.getLogger(UrlRewriteFilter.class);

    @Override
    protected void loadUrlRewriter(FilterConfig filterConfig) throws ServletException {
        ServletContext context = filterConfig.getServletContext();
        String confPath = filterConfig.getInitParameter("confPath");
        boolean modRewriteStyleConf = getModRewriteStyleConf(filterConfig.getInitParameter("modRewriteConf"));
        try {
            final InputStream inputStream = getClass().getClassLoader().getResourceAsStream(confPath);
            final URL confUrl = getClass().getClassLoader().getResource(confPath);

            if (inputStream == null) {
                log.error("unable to find urlrewrite conf file at " + confPath);
                // set the writer back to null
                if (isLoaded()) {
                    log.error("unloading existing conf");
                    destroyUrlRewriter();
                }

            } else {
                Conf conf = new Conf(context, inputStream, confPath, confUrl.toString(), modRewriteStyleConf);
                checkConf(conf);
            }
        } catch (Throwable e) {
            log.error("unloading urlrewrite conf file at " + confPath, e);
            throw new ServletException(e);
        }
    }

    private boolean getModRewriteStyleConf(String modRewriteConf) {
        boolean modRewriteStyleConf = false;
        if (!StringUtils.isBlank(modRewriteConf)) {
            modRewriteStyleConf = "true".equals(StringUtils.trim(modRewriteConf).toLowerCase());
        }
        return modRewriteStyleConf;
    }
}
    • Servlet Filter에 넣기
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
private void initUrlRewriteFilter(ServletContext servletContext, EnumSet<DispatcherType> disps) {
    FilterRegistration.Dynamic urlRewriteFilter =
        servletContext.addFilter("urlRewriteFilter", new UrlRewriteFilter());

    urlRewriteFilter.setInitParameter("confPath", "url-rewrite.xml");
    urlRewriteFilter.setInitParameter("confReloadLastCheck", "-1");
    urlRewriteFilter.setInitParameter("logLevel", "WARM");

    urlRewriteFilter.addMappingForUrlPatterns(disps, true, "/*");
    urlRewriteFilter.setAsyncSupported(true);
}
    • url-rewrite.xml 작성 (위치: src/main/resources)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN" "https://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">

<urlrewrite >
    <!-- default -->
    <rule match-type="regex">
        <condition type="request-uri" operator="notequal">
            ^.*\.(html?|htc|js|css|xml|map|json|ico|bmp|gif|jpe?g|png|svg|eot|woff|woff2|ttf|pdf|swf|txt)$
        </condition>
        <from>^/(.*)$</from>
        <to last="true">/index.html</to>
    </rule>
</urlrewrite>

참고

  • https://github.com/spring-io/sagan/search?utf8=%E2%9C%93&q=urlrewrite.xml&type=


2017년 12월 7일 목요일

Nginx로 Reverse-Proxy 구성

Reverse-Proxy란?
  • 사용자의 요청을 받아서 반대편 네트워크에 있는 웹 서버에 전달하는 역할을 함
  • 단순 요청 전달만 함
  • 로드밸런서로의 역할을 할 수 있음
Nginx로 Reverse-Proxy 설정
그림1) Nginx로 Reverse-Proxy 환경 구성도
  • 정적 리버스 프락시 서버 구성
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# cat /etc/nginx/sites-available/default
upstream sample_proxy {
    server 192.168.56.2:8080;
    server 192.168.56.3:8080;
}
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {
        proxy_pass http://sample_proxy;
    }
}
    • upstream영역에 프락시 대상 호스트의 목록 입력
    • upstream은 proxy할 타겟 서버를 설정을 위해 사용
    • location / 에 대한 모든 요청에 대해서, sample_proxy로 중계한다는 의미
  • 로드 밸런싱 메서드
    • 라운드로빈(Round-robin)은 기본적인  메서드로 모든 서버에 동등하게 요청
      1
      2
      3
      4
      upstream sample_proxy {
          server 192.168.56.2:8080;
          server 192.168.56.3:8080;
      }
      
    • least_conn은 연결이 가장 작은 서버로 요청
      1
      2
      3
      4
      5
      6
      upstream sample_proxy {
          least_conn;
      
          server 192.168.56.2:8080;
          server 192.168.56.3:8080;
      }
      
    • ip_hash는 클라이언트 IP주소를 기준으로 요청을 분배한다. IP주소가 같다면, 동일한 서버로 요청
      1
      2
      3
      4
      5
      6
      upstream sample_proxy {
          ip_hash; 
      
          server 192.168.56.2:8080;
          server 192.168.56.3:8080;
      }
      
    • hash는 유저가 정의한 key나 변수 혹은 이들의 조합을 해시해서 분산
      1
      2
      3
      4
      5
      6
      upstream sample_proxy {
          hash $request_uri consistent;
      
          server 192.168.56.2:8080;
          server 192.168.56.3:8080;
      }
      
    • least_time메서드는 NginX Plus에서 지원, 평균 레이턴시와 연결을 기준으로 검사해서 로드가 적은 서버로 요청
      1
      2
      3
      4
      5
      6
      upstream sample_proxy {
          least_time header; 
      
          server 192.168.56.2:8080;
          server 192.168.56.3:8080;
      }
참고
  • https://www.joinc.co.kr/w/man/12/proxy

2017년 12월 5일 화요일

Spring Data Common 1.x -> 2.x에서 CrudRepository 변동된 점

CrudRepository내에 함수 및 반환형태 변동
  • findOne이 사라짐
  • findById 는 Optional<T> 형태로 반환됨 (* JDK 8을 써야 함)