环境:linux7 内核3.10  2台  192.168.13.111     192.168.13.222

之前在windows整合过单机版的elasticsearch,对于SpringBoot项目来说变动几乎没有,唯一的就是多节点配置下。

2台机器已安装docker

pull elasticsearch镜像

spring boot Quartz集群 spring boot es集群_elasticsearch

每台机器创建三个文件夹分别放数据、日志和配置文件

spring boot Quartz集群 spring boot es集群_java_02

   两台机器都一样的文件夹

需要给文件夹权限chmod 777 elasticsearch6.7.1/      必须,切记!6.x版本必须给权限,必须,必须  

在111的机器config文件夹下面创建elasticsearch.yml配置文件

#集群名称,所有节点的集群名称必须保持一致
cluster.name: elasticsearch
#节点名称
node.name: es111
#允许哪些IP可以访问,全部通过
network.bind_host: 0.0.0.0
#发布到外部服务的IP
network.publish_host: 192.168.13.111
#访问的端口,默认9200
http.port: 9200
#外部服务交互端口,比如java等
transport.tcp.port: 9300
#head插件跨域访问设置为true
http.cors.enabled: true
http.cors.allow-origin: "*"
#可以有资格竞选master
node.master: true
#存储数据 
node.data: true
#集群节点,发现其他服务器中的es服务,可以不指定端口[默认9300],如果是发现同一个服务器中的es服务,#就需要指定端口了  
discovery.zen.ping.unicast.hosts: ["192.168.13.111","192.168.13.222"]
#避免脑裂,一般集群服务器都是奇数,而且设置都是过半+1,这里只有2台,就设置1了
discovery.zen.minimum_master_nodes: 1

在222机器的config文件夹下面创建elasticsearch.yml配置文件:

#集群名称,所有节点的集群名称必须保持一致
cluster.name: elasticsearch
#节点名称
node.name: es222
#允许哪些IP可以访问,全部通过
network.bind_host: 0.0.0.0
#发布到外部服务的IP
network.publish_host: 192.168.13.222
#访问的端口,默认9200
http.port: 9200
#外部服务交互端口,比如java等
transport.tcp.port: 9300
#head插件跨域访问设置为true
http.cors.enabled: true
http.cors.allow-origin: "*"
#可以有资格去竞选master
node.master: true
#存储数据 
node.data: true
#集群节点,发现其他服务器中的es服务,可以不指定端口[默认9300],如果是发现同一个服务器中的es服务,#就需要指定端口了  
discovery.zen.ping.unicast.hosts: ["192.168.13.111","192.168.13.222"]
#避免脑裂,一般集群服务器都是奇数,而且设置都是过半+1,这里只有2台,就设置1了
discovery.zen.minimum_master_nodes: 1

在111机器执行docker命令:看看elasticsearch是否启动

docker run -d --name es111 -p 9200:9200 -p 9300:9300 -v /elasticsearch6.7.1/config:/usr/share/elasticsearch/config -v /elasticsearch6.7.1/data:/usr/share/elasticsearch/data elasticsearch:6.7.1

spring boot Quartz集群 spring boot es集群_java_03

浏览器访问:192.168.13.111:9200看效果,访问不到。ES启动后马上就停了

于是查看日志  docker logs -f es111或者容器ID  内存不足

更换启动方式,给予内存分配

docker run -d --name es111 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" -p 9200:9200 -p 9300:9300 -v /elasticsearch6.7.1/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /elasticsearch6.7.1/data:/usr/share/elasticsearch/data elasticsearch:6.7.1

Xms和Xmx要一样,否则会提示内存错误: bootstrap checks failed
[1]: initial heap size [268435456] not equal to maximum heap size [536870912]; this can cause resize pauses and prevents mlockall from locking the entire heap

在222机器执行同样docker命令(这里取名es222):

docker run -d --name es111 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" -p 9200:9200 -p 9300:9300 -v /elasticsearch6.7.1/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /elasticsearch6.7.1/data:/usr/share/elasticsearch/data elasticsearch:6.7.1

都成功了

spring boot Quartz集群 spring boot es集群_java_04

带*的是主节点

安装elasticsearch-head插件: 

docker pull mobz/elasticsearch-head:5

只需要在其中一台机器安装即可

安装完成执行命令

docker run -d -p 9100:9100 --name es-manager  mobz/elasticsearch-head:5

spring boot Quartz集群 spring boot es集群_elasticsearch_05

整合SpringBoot:

application.yml:  只关注elasticsearch那部分即可

server: 
  port: 8081
  # 下面是配置undertow作为服务器的参数
  undertow: 
    # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程
    io-threads: 4
    # 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
    worker-threads: 20
    # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
    # 每块buffer的空间大小,越小的空间被利用越充分
    buffer-size: 1024
    # 是否分配的直接内存
    direct-buffers: true
    
#启用shutdown
#endpoints: 
 # shutdown: 
   # enable: true
#禁用密码验证
#endpoints: 
  #shutdown: 
    #sensitive: false
#linux关闭的脚本
#curl -X POST host:port/shutdown

#开启shutdown的安全验证
#endpoints: 
  #shutdown: 
    #sensitive: true
    
#验证用户名和密码
#security: 
  #user: 
    #name: admin
    #password: admin
    
#角色
#management: 
  #address: 127.0.0.1
  #port: 8081
  #security: 
    #role: SUPERUSER


spring: 
  datasource: 
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.jdbc.Driver
    driver-class-name: com.mysql.jdbc.Driver
    platform: mysql
    url: jdbc:mysql://120.79.81.103:5306/miniprogram?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
    username: root
    password: admin
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT1FROMDUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    filters: stat,wall
    logSlowSql: true
# ELASTICSEARCH (ElasticsearchProperties)
# Elasticsearch cluster name.
  data:
    elasticsearch:
      cluster-name: elasticsearch
      cluster-nodes: 192.168.13.111:9300,192.168.13.222:9300
      repositories:
        enabled: true
  redis: 
    database: 1
    host: 211.149.199.68
    port: 6379
    password: ******
    timeout: 10000
  activemq: 
    queueName: mvp.queue
    topicName: mvp.topic
    #账号密码
    user: user
    password: user
    #URL of the ActiveMQ broker.
    broker-url: tcp://localhost:61616
    in-memory: false
    #必须使用连接池
    pool: 
      #启用连接池
      enabled: true
      #连接池最大连接数
      max-connections: 5
      #空闲的连接过期时间,默认为30秒
      idle-timeout: 30s
#    jedis:    有默认值,源码:RedisProperties
#      pool:
#        max-active:
#        max-idle:
#        max-wait:
#        min-idle: 
    
mybatis: 
  typeAliasesPackage: com.pinyu.miniprogram.mysql.entity
  mapper-locations: classpath:mapper/**/*Mapper.xml
mapper:
  mappers: com.pinyu.miniprogram.mysql.mappers.BaseMapper
  identity: mysql
  
  
#logging.config: 
#  classpath: test/log4j2_test.xml

IdEntity:

package com.pinyu.miniprogram.mysql.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import com.pinyu.miniprogram.mysql.entity.member.MemberEntity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * @author ypp 创建时间:2018年12月25日 下午1:32:18
 * @Description: TODO(用一句话描述该文件做什么)
 */
@Data // getter、setter
@AllArgsConstructor // 全参构造方法
@NoArgsConstructor // 无参构造方法
@Accessors(chain = true) // 链式编程写法
public class IdEntity implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -9089706482760436909L;

	@Id
	@Column(name = "id")
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@org.springframework.data.annotation.Id
	private Long id;

}

@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)

这3个注解是通用mapper的注解

@org.springframework.data.annotation.Id    这个注解才是elasticsearch的id注解

BaseEntity:

package com.pinyu.miniprogram.mysql.entity;

import java.util.Date;

import javax.persistence.Column;

import com.pinyu.miniprogram.mysql.entity.member.MemberEntity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * @author ypp 创建时间:2018年12月25日 下午1:32:28
 * @Description: TODO(用一句话描述该文件做什么)
 */
@Data // getter、setter
@AllArgsConstructor // 全参构造方法
@NoArgsConstructor // 无参构造方法
@Accessors(chain = true) // 链式编程写法
public class BaseEntity extends IdEntity {

	/**
	 * 
	 */
	private static final long serialVersionUID = 8575696766261326260L;

	@Column(name="creat_id")
	private Integer creatId;

	@Column(name="create_date")
	private Date createDate;

	@Column(name="delete_state")
	private Integer deleteState;// 删除状态 1正常 2已删除

}

BaseEntity的字段没有用到,这是通用mapper设置的字段

BookEntity:

package com.pinyu.miniprogram.mysql.entity.book;

import org.springframework.data.elasticsearch.annotations.Document;

import com.pinyu.miniprogram.mysql.entity.BaseEntity;

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain=true)
@Document(indexName = "book", type = "_doc")
public class BookEntity extends BaseEntity{

    private String title;
    private String author;
    private String postDate;
    
    public BookEntity(Long id, String title,String author,String postDate){
    	setId(id);
    	this.title=title;
    	this.author=author;
    	this.postDate=postDate;
    }

}

@Document(indexName = "book", type = "_doc")   

Document表示elasticsearch的document,indexName索引名称 type就是elasticsearch的type

 

BookRepository:

package com.pinyu.miniprogram.mysql.repositry;

import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import com.pinyu.miniprogram.mysql.entity.book.BookEntity;

public interface BookRepository extends ElasticsearchRepository<BookEntity,Long>{
	
	Page<BookEntity> findByAuthor(String author, Pageable pageable);

    Page<BookEntity> findByTitle(String title, Pageable pageable);

    List<BookEntity> findByTitle(String title);

}

注意ElasticsearchRepository<BookEntity,Long>        里面的Long要和实体类型的id类型保持一致,不然要报错,类型转换异常

BookService:

package com.pinyu.miniprogram.mysql.service.book;

import java.util.List;
import java.util.Optional;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;

import com.pinyu.miniprogram.mysql.entity.book.BookEntity;

public interface BookService {
	
	Optional<BookEntity> findById(Long id);

    BookEntity save(BookEntity blog);

    void delete(BookEntity blog);

    Optional<BookEntity> findOne(Long id);

    List<BookEntity> findAll();

    Page<BookEntity> findByAuthor(String author, PageRequest pageRequest);

    Page<BookEntity> findByTitle(String title, PageRequest pageRequest);

    List<BookEntity> findTitle(String titileKeyword);

    Iterable<BookEntity> saveAll(List<BookEntity> books);

}

BookServiceImpl:

package com.pinyu.miniprogram.mysql.service.book.impl;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import com.pinyu.miniprogram.mysql.entity.book.BookEntity;
import com.pinyu.miniprogram.mysql.repositry.BookRepository;
import com.pinyu.miniprogram.mysql.service.book.BookService;

@Service
public class BookServiceImpl implements BookService{

	@Autowired
	private BookRepository bookRepository;
	
	
	@Override
    public Optional<BookEntity> findById(Long id) {
        //CrudRepository中的方法
        return bookRepository.findById(id);
    }

    @Override
    public BookEntity save(BookEntity blog) {
        return bookRepository.save(blog);
    }

    @Override
    public void delete(BookEntity blog) {
    	bookRepository.delete(blog);
    }

    @Override
    public Optional<BookEntity> findOne(Long id) {
        return bookRepository.findById(id);
    }

    @Override
    public List<BookEntity> findAll() {
        return (List<BookEntity>) bookRepository.findAll();
    }

    @Override
    public Page<BookEntity> findByAuthor(String author, PageRequest pageRequest) {
        return bookRepository.findByAuthor(author,pageRequest);
    }

    @Override
    public Page<BookEntity> findByTitle(String title, PageRequest pageRequest) {
        return bookRepository.findByTitle(title,pageRequest);
    }

    @Override
    public List<BookEntity> findTitle(String titileKeyword) {
        return bookRepository.findByTitle(titileKeyword);
    }
    @Override
    public Iterable<BookEntity> saveAll(List<BookEntity> BookEntitys) {
        return bookRepository.saveAll(BookEntitys);
    }
}

BookController:

package com.pinyu.miniprogram.web.controller.book;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.pinyu.miniprogram.mysql.entity.book.BookEntity;
import com.pinyu.miniprogram.mysql.service.book.BookService;

@Controller
@RequestMapping("/es")
public class BookController {

	@Autowired
    private BookService bookService;

    @RequestMapping("/book/{id}")
    @ResponseBody
    public BookEntity getBookEntityById(@PathVariable Long id){
        Optional<BookEntity> opt =bookService.findById(id);
        BookEntity book=opt.get();
        System.out.println(book);
        return book;
    }

    @RequestMapping("/save")
    @ResponseBody
    public void Save(){
        BookEntity book1=new BookEntity(1L,"ES入门教程","ypp","2018-10-01");
        BookEntity book2=new BookEntity(2L,"从ES入门教程到放弃java","ypp","2018-10-01");
        BookEntity book3=new BookEntity(3L,"mysql从入门到放弃","ypp","2018-10-01");
        BookEntity book4=new BookEntity(4L,"redis从入门到放弃","ypp","2018-10-01");
        BookEntity book5=new BookEntity(5L,"spark从入门到放弃","ypp","2018-10-01");
        BookEntity book6=new BookEntity(6L,"hbase从入门到放弃","ypp","2018-10-01");
        BookEntity book7=new BookEntity(7L,"zookeeper从入门到放弃","ypp","2018-10-01");
        BookEntity book8=new BookEntity(8L,"mq从入门到放弃","ypp","2018-10-01");
        BookEntity book9=new BookEntity(9L,"spring cloud从入门到放弃","ypp","2018-10-01");
        List<BookEntity> books=new ArrayList<>();
        books.add(book1);
        books.add(book2);
        books.add(book3);
        books.add(book4);
        books.add(book5);
        books.add(book6);
        books.add(book7);
        books.add(book8);
        books.add(book9);
        try {
			
        	bookService.saveAll(books);
		} catch (Exception e) {
			e.printStackTrace();
		}
    }

    @RequestMapping("/keyword")
    @ResponseBody
    public List<BookEntity> keyword(@RequestParam("keyword")String keyword){
        return bookService.findTitle(keyword);
    }
}

发送save请求插入

spring boot Quartz集群 spring boot es集群_java_06

插入成功,但是在head视图数据有错误,没有查询到

spring boot Quartz集群 spring boot es集群_java_07

head视图插件里面的请求是失败的,单独拿出来浏览器访问时可以访问到索引数据,应该是哪里没有配置对。111/222浏览器访问都可以拿到,head里面的111/222都拿不到。能证明数据是插入到elasticsearch集群了。视图插件配置有误。请求406.其他是可以看到数据的,后面来修正

spring boot Quartz集群 spring boot es集群_mysql_08

 9条

至此SpringBoot整合elasticsearch集群算成功了