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

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