spring-cloud-kubernetes actual service discovery and polling (including fused)

This article is a "spring-cloud-kubernetes combat series' fourth in the main content is to deploy two applications on kubernetes: Web-Service and Account-Service, a registered discovery capabilities provided by the spring-cloud-kubernetes, achieve Web- service Account-service to call http service provided;

Series list

  1. "Spring-cloud-kubernetes official demo run real"
  2. "Hello spring-cloud-kubernetes"
  3. "Three key knowledge points spring-cloud-kubernetes behind"
  4. "Spring-cloud-kubernetes actual service discovery and polling (including fused)"
  5. 《spring-cloud-kubernetes与SpringCloud Gateway》
  6. "Spring-cloud-kubernetes and k8s of configmap"

Full overview

This paper consists of the following paragraphs that:

  1. Environmental Information
  2. Common SpringCloud registered discover services at a glance
  3. How to achieve registration service analysis found kubernetes
  4. This chapter actual source code download link
  5. Account-Service combat development services (service provider)
  6. Combat development Web-Service service (the service consumer)
  7. Expansion verify ribbon polling capability
  8. The ability to verify the fuse

Environmental Information

The real environmental and version information is as follows:

  1. Operating System: CentOS Linux release 7.6.1810
  2. minikube: 1.1.1
  3. Java:1.8.0_191
  4. Maven:3.6.0
  5. fabric8-maven-plugin plugin: 3.5.37
  6. spring-cloud-kubernetes:1.0.1.RELEASE

Above linux, minikube, java, maven, make sure you have ready, minikube the linux environment installation and startup refer to "Linux Installation Guide minikube" .

Common SpringCloud registered discover services at a glance

SpringCloud environment most important function is a registered discovery service, so when the SpringCloud migrate applications to kubernetes environment and development issues were most concerned about is how to expose their services to go on kubernetes, and how to invoke other micro-services.

Take a look at registration found in ordinary SpringCloud environment, figure comes from spring official blog, the address is: https: //spring.io/blog/2015/07/14/microservices-with-spring,
Here Insert Picture Description

Seen from the figure, the application of Account-Service registers itself to Eureka, this Web-Service with "account-service" will be able to find the address of the Account-Service Service in Eureka, and then successfully sends a request to the Account-Service RestFul, spend it service provided.

How to achieve registration service analysis found kubernetes

If you migrate after the above Web-Service and Account-Service applied to the two kubernetes, registered discovery mechanism becomes a sawed it?
The first: follow the way on the map, it will also be deployed in Eureka on kubernetes, so there is no infrastructure and no kubernetes what difference;
second, is today content to combat the use of spring-cloud-kubernetes framework kubernetes can call the native ability to serve existing SpringCloud application architecture as shown below:
Here Insert Picture Description
This illustration shows, Web-service application to invoke a service Account-service applications, requests a list of services with okhttp to the API Server, API Server receives a request would take to return data to the etcd Web-Service application, so that there is a Web-Service Account-Service information may initiate a request to a plurality of Account-Service Pod polling;

There is a map on details Please note: WebService application does not send the request directly to the service Account-Service in kubernetes created, but sent directly to the concrete Pod, and the reason has this capability, because the spring-cloud-kubernetes frame by a service to get the information of all Pod (endpoint) Account-service corresponding to this reference source logic may KubernetesServerList.java, as follows:

public List<Server> getUpdatedListOfServers() {
        //用namespace和serviceId做条件,得到该服务对应的所有节点(endpoints)信息
        Endpoints endpoints = this.namespace != null
                ? this.client.endpoints().inNamespace(this.namespace)
                        .withName(this.serviceId).get()
                : this.client.endpoints().withName(this.serviceId).get();

        List<Server> result = new ArrayList<Server>();
        if (endpoints != null) {

            if (LOG.isDebugEnabled()) {
                LOG.debug("Found [" + endpoints.getSubsets().size()
                        + "] endpoints in namespace [" + this.namespace + "] for name ["
                        + this.serviceId + "] and portName [" + this.portName + "]");
            }
            //遍历所有的endpoint,取出IP地址和端口,构建成Server实例,放入result集合中
            for (EndpointSubset subset : endpoints.getSubsets()) {

                if (subset.getPorts().size() == 1) {
                    EndpointPort port = subset.getPorts().get(FIRST);
                    for (EndpointAddress address : subset.getAddresses()) {
                        result.add(new Server(address.getIp(), port.getPort()));
                    }
                }
                else {
                    for (EndpointPort port : subset.getPorts()) {
                        if (Utils.isNullOrEmpty(this.portName)
                                || this.portName.endsWith(port.getName())) {
                            for (EndpointAddress address : subset.getAddresses()) {
                                result.add(new Server(address.getIp(), port.getPort()));
                            }
                        }
                    }
                }
            }
        }
        else {
            LOG.warn("Did not find any endpoints in ribbon in namespace ["
                    + this.namespace + "] for name [" + this.serviceId
                    + "] and portName [" + this.portName + "]");
        }
        return result;
    }

Theoretical analysis has been completed, then we began to combat it

Source download

If you do not intend to write code, you can also download the source code from this combat on GitHub, address and link information in the following table:

name link Remark
Project Home https://github.com/zq2599/blog_demos The project's home page on GitHub
git repository address (https) https://github.com/zq2599/blog_demos.git The project's source code repository address, https protocol
git repository address (ssh) [email protected]: zq2599 / blog_demos.git The project's source code repository address, ssh protocol


The git project has multiple folders, Account-Service Source chapter in the spring-cloud-k8s-account- service folder, Web-Service Source under the spring-cloud-k8s-web- service folder, as shown below FIG red box:
Here Insert Picture Description
the following is a detailed process of encoding;

Development and deployment of Account-Service Service

Account-Service service is a very common springboot applications, and spring-cloud-kubernetes nothing to do with:

  1. Create a springboot application by maven, artifactId is the Account-Service , pom.xml as follows:
<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.bolingcavalry</groupId>
    <artifactId>account-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>account-service</name>
    <description>Demo project for Spring Cloud service provider run in kubernetes</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot.version>2.1.1.RELEASE</spring-boot.version>
        <maven-checkstyle-plugin.failsOnError>false</maven-checkstyle-plugin.failsOnError>
        <maven-checkstyle-plugin.failsOnViolation>false</maven-checkstyle-plugin.failsOnViolation>
        <maven-checkstyle-plugin.includeTestSourceDirectory>false</maven-checkstyle-plugin.includeTestSourceDirectory>
        <maven-compiler-plugin.version>3.5</maven-compiler-plugin.version>
        <maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
        <maven-failsafe-plugin.version>2.18.1</maven-failsafe-plugin.version>
        <maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
        <fabric8.maven.plugin.version>3.5.37</fabric8.maven.plugin.version>
        <springcloud.version>2.1.1.RELEASE</springcloud.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <type>pom</type>
                <scope>import</scope>
                <version>${spring-boot.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>${springcloud.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${springcloud.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <!--skip deploy -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>${maven-deploy-plugin.version}</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven-surefire-plugin.version}</version>
                <configuration>
                    <skipTests>true</skipTests>
                    <!-- Workaround for https://issues.apache.org/jira/browse/SUREFIRE-1588 -->
                    <useSystemClassLoader>false</useSystemClassLoader>
                </configuration>
            </plugin>
            <plugin>
                <groupId>io.fabric8</groupId>
                <artifactId>fabric8-maven-plugin</artifactId>
                <version>${fabric8.maven.plugin.version}</version>
                <executions>
                    <execution>
                        <id>fmp</id>
                        <goals>
                            <goal>resource</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>kubernetes</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>io.fabric8</groupId>
                        <artifactId>fabric8-maven-plugin</artifactId>
                        <version>${fabric8.maven.plugin.version}</version>
                        <executions>
                            <execution>
                                <id>fmp</id>
                                <goals>
                                    <goal>resource</goal>
                                    <goal>build</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <enricher>
                                <config>
                                    <fmp-service>
                                        <type>NodePort</type>
                                    </fmp-service>
                                </config>
                            </enricher>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>

Pom.xml be seen from the contents of the above, account-service application is a simple web application, and SpringCloud, spring-cloud-kubernetes do not have any relations, and other springboot only difference is the use of fabric8-maven-plugin plugin, you can easily the application will be deployed to kubernetes environment;

  1. application.yml follows, is still very simple:
spring:
  application:
    name: account-service

server:
  port: 8080
  1. Is the AccountController external service provider, the method getName returns the hostname of the current container, a method for health response kubernetes two probes, a method for ribbonPing response to the caller's side ribbon and services, they will call this interface to determine the current service It is normal:
@RestController
public class AccountController {

    private static final Logger LOG = LoggerFactory.getLogger(AccountController.class);

    private final String hostName = System.getenv("HOSTNAME");

    /**
     * 探针检查响应类
     * @return
     */
    @RequestMapping("/health")
    public String health() {
        return "OK";
    }

    @RequestMapping("/")
    public String ribbonPing(){
        LOG.info("ribbonPing of {}", hostName);
        return hostName;
    }

    /**
     * 返回hostname
     * @return 当前应用所在容器的hostname.
     */
    @RequestMapping("/name")
    public String getName() {
        return this.hostName
                + ", "
                + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }
}
  1. The source of such works on minikube machine, make sure maven set correctly, and then execute the following command in the pom.xml file directory, build the project can be compiled and deployed to the kubernetes:
mvn clean install fabric8:deploy -Dfabric8.generator.from=fabric8/java-jboss-openjdk8-jdk -Pkubernetes

After the successful implementation of the console output is as follows:

...
[INFO] Installing /usr/local/work/k8s/ribbon/spring-cloud-k8s-account-service/target/classes/META-INF/fabric8/kubernetes.json to /root/.m2/repository/com/bolingcavalry/account-service/0.0.1-SNAPSHOT/account-service-0.0.1-SNAPSHOT-kubernetes.json
[INFO] 
[INFO] <<< fabric8-maven-plugin:3.5.37:deploy (default-cli) < install @ account-service <<<
[INFO] 
[INFO] 
[INFO] --- fabric8-maven-plugin:3.5.37:deploy (default-cli) @ account-service ---
[INFO] F8: Using Kubernetes at https://192.168.121.133:8443/ in namespace default with manifest /usr/local/work/k8s/ribbon/spring-cloud-k8s-account-service/target/classes/META-INF/fabric8/kubernetes.yml 
[INFO] Using namespace: default
[INFO] Updating a Service from kubernetes.yml
[INFO] Updated Service: target/fabric8/applyJson/default/service-account-service.json
[INFO] Using namespace: default
[INFO] Updating Deployment from kubernetes.yml
[INFO] Updated Deployment: target/fabric8/applyJson/default/deployment-account-service.json
[INFO] F8: HINT: Use the command `kubectl get pods -w` to watch your pods start up
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  11.941 s
[INFO] Finished at: 2019-06-16T19:00:51+08:00
[INFO] ------------------------------------------------------------------------
  1. Deployment and service on the check kubernetes is normal:
[root@minikube spring-cloud-k8s-account-service]# kubectl get deployments
NAME              READY   UP-TO-DATE   AVAILABLE   AGE
account-service   1/1     1            1           69m
[root@minikube spring-cloud-k8s-account-service]# kubectl get services
NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
account-service   NodePort    10.105.157.201   <none>        8080:32596/TCP   69m
kubernetes        ClusterIP   10.96.0.1        <none>        443/TCP          8d
  1. minikube the service command can get access to the address specified services:
[root@minikube spring-cloud-k8s-account-service]# minikube service account-service --url
http://192.168.121.133:32596

Visible account-service service can be accessed through this url: http: //192.168.121.133: 32596

  1. With a browser to access the address: http: //192.168.121.133: 32596 / name , as shown below, you can access the service account-service offer:
    Here Insert Picture Description
    now account-service service is in place, followed by the development and deployment of web-service application.

    Development and deployment of Web-Service Service

    Web-Service is a service springboot application uses registered discoverability spring-cloud-kubernetes provided access to designated polling services all pod:
  2. Create a springboot application by maven, artifactId is a Web-Service , pom.xml as follows, to focus on is spring-cloud-starter-kubernetes- ribbon dependency:
<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.bolingcavalry</groupId>
    <artifactId>web-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>web-service</name>
    <description>Demo project for Spring Cloud service consumer run in kubernetes</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot.version>2.1.1.RELEASE</spring-boot.version>
        <maven-checkstyle-plugin.failsOnError>false</maven-checkstyle-plugin.failsOnError>
        <maven-checkstyle-plugin.failsOnViolation>false</maven-checkstyle-plugin.failsOnViolation>
        <maven-checkstyle-plugin.includeTestSourceDirectory>false</maven-checkstyle-plugin.includeTestSourceDirectory>
        <maven-compiler-plugin.version>3.5</maven-compiler-plugin.version>
        <maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
        <maven-failsafe-plugin.version>2.18.1</maven-failsafe-plugin.version>
        <maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
        <fabric8.maven.plugin.version>3.5.37</fabric8.maven.plugin.version>
        <springcloud.kubernetes.version>1.0.1.RELEASE</springcloud.kubernetes.version>
        <springcloud.version>2.1.1.RELEASE</springcloud.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <type>pom</type>
                <scope>import</scope>
                <version>${spring-boot.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-kubernetes-core</artifactId>
            <version>${springcloud.kubernetes.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-kubernetes-discovery</artifactId>
            <version>${springcloud.kubernetes.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
            <version>${springcloud.kubernetes.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-commons</artifactId>
            <version>${springcloud.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>${springcloud.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${springcloud.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>${springcloud.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>${springcloud.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <!--skip deploy -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>${maven-deploy-plugin.version}</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven-surefire-plugin.version}</version>
                <configuration>
                    <skipTests>true</skipTests>
                    <!-- Workaround for https://issues.apache.org/jira/browse/SUREFIRE-1588 -->
                    <useSystemClassLoader>false</useSystemClassLoader>
                </configuration>
            </plugin>
            <plugin>
                <groupId>io.fabric8</groupId>
                <artifactId>fabric8-maven-plugin</artifactId>
                <version>${fabric8.maven.plugin.version}</version>
                <executions>
                    <execution>
                        <id>fmp</id>
                        <goals>
                            <goal>resource</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>kubernetes</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>io.fabric8</groupId>
                        <artifactId>fabric8-maven-plugin</artifactId>
                        <version>${fabric8.maven.plugin.version}</version>
                        <executions>
                            <execution>
                                <id>fmp</id>
                                <goals>
                                    <goal>resource</goal>
                                    <goal>build</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <enricher>
                                <config>
                                    <fmp-service>
                                        <type>NodePort</type>
                                    </fmp-service>
                                </config>
                            </enricher>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>
  1. application.yml reads as follows, increasing the fusing configurations:
spring:
  application:
    name: web-service

server:
  port: 8080

backend:
  ribbon:
    eureka:
      enabled: false
    client:
      enabled: true
    ServerListRefreshInterval: 5000

hystrix.command.BackendCall.execution.isolation.thread.timeoutInMilliseconds: 5000
hystrix.threadpool.BackendCallThread.coreSize: 5
  1. Create a configuration class RibbonConfiguration a ribbon of:
package com.bolingcavalry.webservice;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AvailabilityFilteringRule;
import com.netflix.loadbalancer.IPing;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.PingUrl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;

/**
 * @Description: ribbon配置类
 * @author: willzhao E-mail: [email protected]
 * @date: 2019/6/16 11:52
 */
public class RibbonConfiguration {

    @Autowired
    IClientConfig ribbonClientConfig;

    /**
     * 检查服务是否可用的实例,
     * 此地址返回的响应的返回码如果是200表示服务可用
     * @param config
     * @return
     */
    @Bean
    public IPing ribbonPing(IClientConfig config){
        return new PingUrl();
    }

    /**
     * 轮询规则
     * @param config
     * @return
     */
    @Bean
    public IRule ribbonRule(IClientConfig config){
        return new AvailabilityFilteringRule();
    }
}
  1. Application class as follows to start, pay attention to increasing the service discovery, fuse, ribbon configuration also defines restTemplte example, note @LoadBalanced notes:
package com.bolingcavalry.webservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@RibbonClient(name="account-service", configuration = RibbonConfiguration.class)
public class WebServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(WebServiceApplication.class, args);
    }

    @LoadBalanced
    @Bean
    RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
  1. Http interface logic remote call account-service is put into service class AccountService, note the URL with the name of the service account-service :
package com.bolingcavalry.webservice;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Description: 这里面封装了远程调用account-service提供服务的逻辑
 * @author: willzhao E-mail: [email protected]
 * @date: 2019/6/16 12:21
 */
@Service
public class AccountService {

    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "getFallbackName" ,commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000") })
    public String getDataFromSpringCloudK8SProvider(){
        return this.restTemplate.getForObject("http://account-service/name", String.class);
    }

    /**
     * 熔断时调用的方法
     * @return
     */
    private String getFallbackName() {
        return "Fallback"
                + ", "
                + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }
}
  1. Finally, in response WebServiceController class web request, there AccountService call service, after we initiated the request from the web, web-service will account-service long-distance call services:
package com.bolingcavalry.webservice;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description: 测试用的controller,会远程调用account-service的服务
 * @author: willzhao E-mail: [email protected]
 * @date: 2019/6/16 11:46
 */
@RestController
public class WebServiceController {

    @Autowired
    private AccountService accountService;

    /**
     * 探针检查响应类
     * @return
     */
    @RequestMapping("/health")
    public String health() {
        return "OK";
    }

    /**
     * 远程调用account-service提供的服务
     * @return 多次远程调返回的所有结果.
     */
    @RequestMapping("/account")
    public String account() {

        StringBuilder sbud = new StringBuilder();

        for(int i=0;i<10;i++){
            sbud.append(accountService.getDataFromSpringCloudK8SProvider())
                .append("<br>");
        }

        return sbud.toString();
    }
}
  1. The source of such works on minikube machine, make sure maven set correctly, and then execute the following command in the pom.xml file directory, build the project can be compiled and deployed to the kubernetes:
mvn clean install fabric8:deploy -Dfabric8.generator.from=fabric8/java-jboss-openjdk8-jdk -Pkubernetes

After the successful implementation of the console output is as follows:

...
[INFO] Installing /usr/local/work/k8s/ribbon/spring-cloud-k8s-web-service/target/classes/META-INF/fabric8/kubernetes.json to /root/.m2/repository/com/bolingcavalry/web-service/0.0.1-SNAPSHOT/web-service-0.0.1-SNAPSHOT-kubernetes.json
[INFO] 
[INFO] <<< fabric8-maven-plugin:3.5.37:deploy (default-cli) < install @ web-service <<<
[INFO] 
[INFO] 
[INFO] --- fabric8-maven-plugin:3.5.37:deploy (default-cli) @ web-service ---
[INFO] F8: Using Kubernetes at https://192.168.121.133:8443/ in namespace default with manifest /usr/local/work/k8s/ribbon/spring-cloud-k8s-web-service/target/classes/META-INF/fabric8/kubernetes.yml 
[INFO] Using namespace: default
[INFO] Creating a Service from kubernetes.yml namespace default name web-service
[INFO] Created Service: target/fabric8/applyJson/default/service-web-service.json
[INFO] Using namespace: default
[INFO] Creating a Deployment from kubernetes.yml namespace default name web-service
[INFO] Created Deployment: target/fabric8/applyJson/default/deployment-web-service.json
[INFO] F8: HINT: Use the command `kubectl get pods -w` to watch your pods start up
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  12.792 s
[INFO] Finished at: 2019-06-16T19:24:21+08:00
[INFO] ------------------------------------------------------------------------
  1. Deployment and service on the check kubernetes is normal:
[root@minikube spring-cloud-k8s-web-service]# kubectl get deployments
NAME              READY   UP-TO-DATE   AVAILABLE   AGE
account-service   1/1     1            1           109m
web-service       1/1     1            1           18m
[root@minikube spring-cloud-k8s-web-service]# kubectl get svc
NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
account-service   NodePort    10.105.157.201   <none>        8080:32596/TCP   109m
kubernetes        ClusterIP   10.96.0.1        <none>        443/TCP          8d
web-service       NodePort    10.99.211.179    <none>        8080:30519/TCP   18m
  1. minikube the service command can get access to the address specified services:
[root@minikube spring-cloud-k8s-web-service]# minikube service web-service --url
http://192.168.121.133:30519

Visible web-service service can be accessed through this url: http: //192.168.121.133: 30519

  1. With a browser to access the address: http: //192.168.121.133: 30519 / account,, to show the page contents shown below are web-service call to account-service interface returns proved registered capability found on kubernetes normal:
    Here Insert Picture Description

    Expansion verify ribbon polling capability

    While web-service account-service service can be called normal, but the visit is always a pod, then we have to account-service of the pod for expansion, will adjust the number to two, to see if the web-service can be polled calling each account-service of the pod:
  2. Execute the following command to adjust the number of the pod 2:
kubectl scale --replicas=2 deployment account-service
  1. Checking account-service of the pod, the two have been found (account-service-5554576647-m29xr and account-service-5554576647-zwwml):
[root@minikube spring-cloud-k8s-web-service]# kubectl get pods
NAME                               READY   STATUS    RESTARTS   AGE
account-service-5554576647-m29xr   1/1     Running   0          53m
account-service-5554576647-zwwml   1/1     Running   0          20s
web-service-6d775855c7-7lkvr       1/1     Running   0          29m
  1. With the browser to access the address: http: //192.168.121.133: 30519 / account, as shown below, account-sercice returned hostname has become two, front and found consistent name pod, showing web-service indeed visited more than account-service of the pod by ribbon poll:
    Here Insert Picture Description

    The ability to verify the fuse

    Then verify whether web-service configuration service can be blown into force:
  2. Execute the following command to delete the account-service of deployment:
kubectl delete deployment account-service
  1. Another browser to access the address: http: //192.168.121.133: 30519 / account, as shown, "Fallback" on the following page is a way to configure content fusing returned, showing that the fuse has been configured to take effect:
    Here Insert Picture Description
  2. Pom.xml back to the position where the web-service to perform the following command, which will rebuild the deployment of a web-service service:
mvn clean install fabric8:deploy -Dfabric8.generator.from=fabric8/java-jboss-openjdk8-jdk -Pkubernetes
  1. Another browser to access the address: http: //192.168.121.133: 30519 / account, as shown below, the service successfully restored:
    Here Insert Picture Description

At this point, spring-cloud-kubernetes service discovery and polling combat (including fuse) to be completed, and the use of information provided by the API Server, spring-cloud-kubernetes original raw kubernetes services to the SpringCloud applications to help micro-traditional services kubernetes better integration in the environment, if you are considering moving applications to the kubernetes, I hope this can give you some reference.

I welcome the attention of the public numbers: programmer Chen Xin

Here Insert Picture Description

Guess you like

Origin www.cnblogs.com/bolingcavalry/p/11457074.html