spring cloud/mesos:在mesos上运行高可用的eureka服务发现

1 创建maven项目

spring cloud使用的版本是Brixton.M5,docker-maven-plugin使用的版本是0.4.1。
pom.xml文件代码如下:

<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.szss.genisys</groupId>
    <artifactId>discovery</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>discovery</name>
    <description>spring cloud eureka</description>
    <parent>
        <groupId>com.szss.genisys</groupId>
        <artifactId>genisys-parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>${docker.plugin.version}</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>build</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
                    <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2 创建eureka服务

程序入口:

@SpringBootApplication
@EnableEurekaServer
public class DiscoveryApplication {
    public static void main(String[] args) {
        SpringApplication.run(DiscoveryApplication.class, args);
    }
}

resources/bootstrap.xml:

info:
  name: discovery-service
  version:  ${project.version}

server:
  port: 8761

spring:
  profiles:
    active: ${maven_spring.profiles.active}
  application:
    name: discovery

security:
  user:
    name: ${eureka.username:zcg}
    password: ${eureka.password:123456}

resources/application.yml:

---
spring:
  profiles: dev

eureka:
  host: localhost
  instance:
    hostname: localhost
    metadata-map:
      instanceId: ${spring.application.name}:${random.value}
  client:
    fetch-registry: false
    register-with-eureka: false
    serviceUrl:
      defaultZone: http://${eureka.username:zcg}:${eureka.password:123456}@localhost:8761/eureka/

---
spring:
  profiles: peer01

eureka:
  instance:
    hostname: ${eureka.instance.hostname}
    metadata-map:
      instanceId: ${spring.application.name}:${random.value}
  client:
    serviceUrl:
      defaultZone: http://${eureka.username:zcg}:${eureka.password:123456}@${eureka.defaultZone.host}:${eureka.defaultZone.port:8761}/eureka/

---
spring:
  profiles: peer02

eureka:
  instance:
    hostname: ${eureka.instance.hostname}
    metadata-map:
      instanceId: ${spring.application.name}:${random.value}
  client:
    serviceUrl:
      defaultZone: http://${eureka.username:zcg}:${eureka.password:123456}@${eureka.defaultZone.host}:${eureka.defaultZone.port:8761}/eureka/

注:有关erueka高可用内容请参看http://cloud.spring.io/spring-cloud-static/spring-cloud.html#_peer_awareness。上面定义很多变量可以可用mesos的环境变量来赋值,如eureka.defaultZone.host等

docker/Dockerfile:

#使用daocloud的java8镜像
FROM daocloud.io/library/java:8
#镜像创建人
MAINTAINER sxt
#附加卷
VOLUME /tmp
#添加jar包
ADD discovery-1.0.0-SNAPSHOT.jar app.jar
#修改jar包日期
RUN bash -c "touch app.jar"
#运行app,并指定端口号
ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -jar /app.jar --server.port=$PORT0

注意:此处没有使用EXPOSE指定暴露端口,而是使用spring boot的程序参数server.port来设置端口号,$PORT0为mesos的环境变量,表示分配给容器的一组主机端口号中的第一个,这样可以让容器内部的端口号和主机端口号保持一致。

3 打包镜像

需要事先准备docker环境,进入docker命令行,在项目目录下执行mvn package命令,打包maven项目,同时生成该程序的镜像。

将镜像推送到registry服务上,本过程不再累述。如何在mesos运行docker registry请参看文章http://blog.csdn.net/zhuchuangang/article/details/51286308

4 在mesos上运行eureka

环境准备:mesos/marathon/docker的安装和环境配置请参考http://blog.csdn.net/zhuchuangang/article/details/51043864

进入marathon页面,点击创建应用,点击弹出框右上角的切换至json模式按钮,将下面内容做部分修改后,粘贴到文本框内提交。或者直接使用marathon API接口也可以。

在marathon上执行下面代码:

{
    "id":"discovery01",
    "cpus":1,
    "mem":256,
    "instances":1,
    "container":{
        "type":"DOCKER",
        "docker":{
            "network":"BRIDGE",
            "image":"172.16.120.136:31000/discovery",
            "portMappings":[
                {
                    "containerPort":0,
                    "hostPort":31761,
                    "servicePort":0,
                    "protocol":"tcp",
                    "name":"http"
                }
            ]
        }
    },
    "env":{
        "spring.profiles.active":"peer01",
        "eureka.instance.hostname":"172.16.120.137",
        "eureka.defaultZone.host":"172.16.120.138",
        "eureka.defaultZone.port":"31762"
    },
    "constraints":[
        [
            "hostname",
            "CLUSTER",
            "172.16.120.137"
        ]
    ],
    "healthChecks":[
        {
            "protocol":"HTTP",
            "path":"/health",
            "portIndex":0,
            "gracePeriodSeconds":300,
            "intervalSeconds":60,
            "timeoutSeconds":20,
            "maxConsecutiveFailures":3
        }
    ]
}

{
    "id":"discovery02",
    "cpus":1,
    "mem":256,
    "instances":1,
    "container":{
        "type":"DOCKER",
        "docker":{
            "network":"BRIDGE",
            "image":"172.16.120.136:31000/discovery",
            "portMappings":[
                {
                    "containerPort":0,
                    "hostPort":31762,
                    "servicePort":0,
                    "protocol":"tcp",
                    "name":"http"
                }
            ]
        }
    },
    "env":{
        "spring.profiles.active":"peer02",
        "eureka.instance.hostname":"172.16.120.138",
        "eureka.defaultZone.host":"172.16.120.137",
        "eureka.defaultZone.port":"31761"
    },
    "constraints":[
        [
            "hostname",
            "CLUSTER",
            "172.16.120.138"
        ]
    ],
    "healthChecks":[
        {
            "protocol":"HTTP",
            "path":"/health",
            "portIndex":0,
            "gracePeriodSeconds":300,
            "intervalSeconds":60,
            "timeoutSeconds":20,
            "maxConsecutiveFailures":3
        }
    ]
}

注意:端口映射处容器内部端口号containerPort设为0,表示和hostPort保持一致。
有关marathon端口配置请参考:http://blog.csdn.net/zhuchuangang/article/details/51167845

有关marathon约束配置请参考:http://blog.csdn.net/zhuchuangang/article/details/51147967

有关marathon健康检查配置请参考:http://blog.csdn.net/zhuchuangang/article/details/51120177

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章