频道栏目
首页 > 资讯 > Linux > 正文

使用apache进行反代tomacat

17-11-30        来源:[db:作者]  
收藏   我要投稿
最近开始重构elasicsearch+springboot+spring data elasticsearch的东西
由于近期更新了elasticsearch 5.x /6.x,大家都忙着尝鲜,不过其中整合框架的过程中遇到了很多的问题
在复写项目的过程中,有重新温习了一下spring data elasticsearch 的操作,我当前尝试的是spring-data-elasticsearch 3.0.1.RELEASE版本,比对以前的一些操作修改的不多,就是一些save=>saveAll,findOne=>findById,findAll=>findAllByIds等等,底层的操作原理没有影响,如果会的同志应当不会太困扰 后期还会对transportClient的使用和框架整合ES的searchquery的介绍
以下是旧版本的spring-data-elasticsearch +java的操作:
1、封装数据库基本CRUD(创建(Create)、更新(Update)、读取(Retrieve)和删除(Delete))
public interface CrudRepository
 extends Repository {

  S save(S entity);

 T findOne(ID primaryKey);    

 Iterable findAll();     

 Long count();          

 void delete(T entity);     

 boolean exists(ID primaryKey); 

 // … more functionality omitted.
}
2、分页排序查询
public interface PagingAndSortingRepository
 extends CrudRepository {

 Iterable findAll(Sort sort);

 Page findAll(Pageable pageable);
}

//Accessing the second page by a page size of 20
PagingAndSortingRepository repository = // … get access to a bean
Page users = repository.findAll(new PageRequest(1, 20));
3、计数
public interface UserRepository extends CrudRepository {

 Long countByLastname(String lastname);
}
4、删除
public interface UserRepository extends CrudRepository {

 Long deleteByLastname(String lastname);

 List removeByLastname(String lastname);

}
5、自定义查询方法自动注入
声明一个接口继承Repository
interface PersonRepository extends Repository {
List findByLastname(String lastname);
}
保证注入了elasticsearch配置
在bootstrap.yml中写入了spring-data-elasticsearch的配置文件将自动注入
注入调用
public class SomeClient {

 @Autowired
 private PersonRepository repository;

 public void doSomething() {
  List persons = repository.findByLastname("Matthews");
 }
}
6、支持Java8 Stream查询和sql语句查询
@Query("select u from User u")
Stream findAllByCustomQueryAndStream();

Stream readAllByFirstnameNotNull();

@Query("select u from User u")
Stream streamAllPaged(Pageable pageable);

try (Stream stream = repository.findAllByCustomQueryAndStream()) {
 stream.forEach(…);
}
7、支持异步查询
@Async
Future findByFirstname(String firstname);        

@Async
CompletableFuture findOneByFirstname(String firstname);

@Async
ListenableFuture findOneByLastname(String lastname);
支持原生es JavaAPI
 
1、NativeSearchQueryBuilder构建查询
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;

SearchQuery searchQuery = new NativeSearchQueryBuilder()
  .withQuery(matchAllQuery())
  .withFilter(boolFilter().must(termFilter("id", documentId)))
  .build();

Page sampleEntities =
  elasticsearchTemplate.queryForPage(searchQuery,SampleEntity.class);
2、利用Scan和Scroll进行大结果集查询
SearchQuery searchQuery = new NativeSearchQueryBuilder()
  .withQuery(matchAllQuery())
  .withIndices("test-index")
  .withTypes("test-type")
  .withPageable(new PageRequest(0,1))
  .build();
String scrollId = elasticsearchTemplate.scan(searchQuery,1000,false);
List sampleEntities = new ArrayList();
boolean hasRecords = true;
while (hasRecords){
  Page page = elasticsearchTemplate.scroll(scrollId, 5000L , new ResultsMapper()
  {
    @Override
    public Page mapResults(SearchResponse response) {
      List chunk = new ArrayList();
      for(SearchHit searchHit : response.getHits()){
        if(response.getHits().getHits().length <= 0) {
          return null;
        }
        SampleEntity user = new SampleEntity();
        user.setId(searchHit.getId());
        user.setMessage((String)searchHit.getSource().get("message"));
        chunk.add(user);
      }
      return new PageImpl(chunk);
    }
  });
  if(page != null) {
    sampleEntities.addAll(page.getContent());
    hasRecords = page.hasNextPage();
  }
  else{
    hasRecords = false;
  }
  }
}
3、获取client实例进行节点操作,可以自行封装Util方法
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;

public void searchHelper() throws IOException {

    //节点客户端
    // on startup
//    Node node = nodeBuilder().clusterName("syncwt-es").client(true).node();
//    Client nodeClient = node.client();

    //传输客户端
//    Settings settings = Settings.settingsBuilder().build();
//    Client transportClient = TransportClient.builder().settings(settings).build();

    Client transportClient = elasticsearchTemplate.getClient();

    Customer customer = new Customer("Alice", "Smith");

    // instance a json mapper
    ObjectMapper mapper = new ObjectMapper(); // create once, reuse

    // generate json
    String json = mapper.writeValueAsString(customer);
    System.out.println("--------------------------------jackson mapper");
    System.out.println(json);

    XContentBuilder builder = jsonBuilder()
        .startObject()
        .field("firstName", "Alice")
        .field("latName", "Smith")
        .endObject();
    System.out.println("--------------------------------jsonBuilder");
    System.out.println(builder.string());

    IndexResponse response = transportClient.prepareIndex("es-customer", "customer")
        .setSource(jsonBuilder()
            .startObject()
            .field("firstName", "Alice")
            .field("latName", "Smith")
            .endObject()
        )
        .execute()
        .actionGet();

    System.out.println("--------------------------------response");
    System.out.println(response.toString());

    // on shutdown
//    node.close();
//    nodeClient.close();
    transportClient.close();

  }
起源

在大部分的生产环境中,基本上使用的都是java程序,从而促进了各种应用程序中间件的产生,在这里大概有几种,tomcat作为最著名的开源servlet容器,jboss也是开源的,而且有管理界面,主要是redhat的,而weblogic则是oracle的商业中间件,而webspare则是IBM的商业中间件,其他的几个例如jetty,resin用的也就比较少了。

在安装tomcat的时候,每次首先需要安装的是jdk,提供jvm虚拟机,jre运行环境,从而每次安装jdk的时候,有几种选择,生产环境基本上使用的都是openjdk,不会产生版权的问题,在开发环境一般使用的是oracle的jdk。在安装完jdk之后,一般都要输出一个环境变量为JAVA_HOME。

在java中,JVM也分为几种,一种是oracle的JRokit虚拟机,主要是使用在weblogic上面;一种是IBM的J9虚拟机,主要使用在IBM的webspare中;一种则是Hotspot,主要使用在openJDK上面。

在生产环境中,servlet的变化为,tomcat——webspare——jboss,小的时候使用开源的,因为免费;慢慢变大,因为维护问题,变成收费;越来越大,又采取了开源,因为免费。前任使用的是weblogic。

配置apache反代tomcat

客户端浏览器发送http请求到apache,然后apache将用户的请求反响代理到后端的tomcat服务器之中,在apache进行反代的时候,可以使用http协议或者是ajp协议,而ajp协议的运行效率比http效率更高,从而一般使用的是ajp协议。

apache在进行反向代理的时候,必须存在几个模块,具体如下:

[root@mogilenode2 extra]# httpd -M |grep proxy

proxy_module (shared)

proxy_connect_module (shared)

proxy_ftp_module (shared)

proxy_http_module (shared)

proxy_scgi_module (shared)

proxy_ajp_module (shared)

proxy_balancer_module (shared)

Syntax OK

在进行编译安装的时候,默认是不会安装代理的模块的,从而在编译的时候可以添加选项,–enable-proxy,–enable-proxy-http,–enable-proxy-ajp,如果已经安装完成,也可以采用DSO的机制,使用命令apxs -ica mod_proxy.c来进行动态装载模块。

apache的主要配置文件如下:

[root@mogilenode2 extra]# cat httpd-vhosts.conf

NameVirtualHost *:80

DocumentRoot “/usr/local/apache/htdocs”

ServerName www.kel.com

ServerAlias kel.com

ProxyVia On

ProxyRequests Off

ProxyPreserveHost On

ProxyPass /status !

ProxyPass  / ajp://192.168.1.238:8009/

ProxyPassReverse  / ajp://192.168.1.238:8009/

#ProxyPass  / http://192.168.1.238:8080/

#ProxyPassReverse  / http://192.168.1.238:8080/

ErrorLog “logs/www.kel.com-error_log”

CustomLog “logs/www.kel.com-access_log” common

SetHandler server-status

Order allow,deny

Allow from all

在配置文件中,主要参数分别介绍如下:ServerName表示主机名,主要用来区分虚拟主机,ProxyVia 主要是给http添加头部响应信息,表示经过了此apache服务器,ProxyRequests 主要是表示使用的正向代理还是反向代理,Off表示使用的是反响代理,ProxyPreserverHost表示是否将主机名反向代理给后端主机,当tomcat有多个虚拟主机的时候,需要开启,ProxyPass主要用来表示反响代理到后端的哪个主机,当使用感叹号的时候,表示不反代,由apache直接响应,需要反代的时候,需要写上后端的协议,主机名和端口号,ProxyPass主要是为了解决重定向的问题,其他的两个为日志信息,ServerAlias表示主机别名,用这个名称也可以进行访问,status主要是用来查看apache的状态页面信息。

查看tomcat的默认监听的进程:

[root@mogilenode3 ~]# ps -ef|grep java

root      3166     1  0 17:08 pts/0    00:00:25 /usr/java/latest/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -classpath /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrap start

root      3219   863  0 18:00 pts/0    00:00:00 grep java

[root@mogilenode3 ~]# netstat -tnlp|grep java

tcp        0      0 :::8080                     :::*                        LISTEN      3166/java

tcp        0      0 ::ffff:127.0.0.1:8005       :::*                        LISTEN      3166/java

tcp        0      0 :::8009                     :::*                        LISTEN      3166/java

[root@mogilenode3 ~]# pstree -p 3166|wc -l

40

根据上面可以看到,默认tomcat监听了三个端口,也就是三个连接器connector,其中8080使用的是http协议,主要用来接受用户请求响应,8005监听的本地localhost的地址,主要是用来管理tomcat进程,而8009使用的是ajp协议。在使用apache进行反代的时候,可以看到配置文件中,当使用http协议反代的时候,使用的端口是8080,当使用ajp协议反代的时候,使用的端口是8009.可以看到默认情况下,tomcat开启了40个线程。

查看管理进程的命令使用:

[root@mogilenode3 ~]# telnet 127.0.0.1 8005(直接关闭tomcat服务)

Trying 127.0.0.1…

Connected to 127.0.0.1.

Escape character is ‘^]’.

SHUTDOWN

Connection closed by foreign host.

[root@mogilenode3 ~]# ps -ef|grep java

root      3244   863  0 18:13 pts/0    00:00:00 grep java
测试

使用网页测试,在使用网页测试的时候,主要修改hosts的域名解析地址:

查看响应头信息如下(会看到在apache中添加的指令ProxyVia添加的首部信息):

当关闭tomcat服务之后,服务端的响应如下所示:

[root@mogilenode2 ~]# curl -I http://www.kel.com

HTTP/1.1 503 Service Temporarily Unavailable

Date: Sat, 23 Sep 2017 22:27:37 GMT

Connection: close

Content-Type: text/html; charset=iso-8859-1

在查看响应码的时候,状态码为503,表示服务暂时不可用,这种可以作为在生产环境中出问题判断问题处在哪里。

吐槽一下apache,apache做为最经典的web服务器,占用的市场份额,那么大,语法太复杂了,和nginx比起来一个天上一个地下,在进行动静分离的时候,nginx更加适合,在使用和tomcat结合的时候,apache适合点,毕竟都是apache旗下的产物,更容易结合,而且有专门的协议ajp来进行传输。

httpd本来就复杂,然后IBM还弄了一个webspare,俗称WAS,结合的方式就是用httpd,然后摇身一变编程了IHS,语法变得更加复杂,在进行反向代理负载均衡的时候,简直就是一坨屎,不想吐槽,然而很多人追求稳定性,说webspare,然而在使用集群的时候,体验并不是那么的好。

使用nginx,更简单易用的web服务器。

web服务器统计数据:


相关TAG标签
上一篇:刚配置好的hive进入不了问题的解决方法
下一篇:在dfs中,如果数量减小一半使用Meet-in-the-middle技巧能够节约很多时间
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站