Spring Cloud的註冊中心和服務者,消費者的構建

Spring Cloud的註冊中心和服務者,消費者的構建

註冊中心Eureka:

新建項目stu-eureka:

StuEurekaApplication:

package com.demo.stueureka;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

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

}


application.yml:

server:
  port: 8761
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
     defaultZone: http://localhost:8761/eureka

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.demo</groupId>
    <artifactId>stu-eureka</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>stu-provider</name>
    <description>Demo project for Spring Boot</description>
    <!-- 引入spring boot的依賴 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.1.RELEASE</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-eureka-server</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>RELEASE</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <!-- 引入spring cloud的依賴 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Camden.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <!-- 添加spring-boot的maven插件 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

配置安全:

在pom.xml中加入如下的依賴:(但是建議springBoot的版本爲1.2或者更高,一般1.5左右可以)

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
</dependency>

更改yml的配置如下:

security:
 basic:
   enabled: true
 user:
   name: user
   password: password123
server:
  port: 8761
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://user:password123@localhost:8761/eureka
  server:
    enable-self-preservation: false  #關閉自我保護
    eviction-interval-timer-in-ms: 60


服務提供者:

新建項目stu-provider:

StuProviderApplication:

package com.demo.stuprovider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
@EnableAutoConfiguration
@SpringBootApplication
@EnableEurekaClient
//@EnableDiscoveryClient//兩者任選
public class StuProviderApplication {

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

}

StudentController

package com.demo.stuprovider.controller;

import com.demo.stuprovider.entity.Student;
import com.demo.stuprovider.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

@RestController
@RequestMapping("/")
public class StudentController {

    @Autowired
    private StudentService studentService;

    @RequestMapping("teststu")
    public String teststu() {

        return "kjlklkll";

    }
    @GetMapping("/getAll/{id}")
    public Student getAll(@PathVariable("id")Integer id){
        System.out.println("stu-provide:localhost:7900==>消費者查詢學生時間:"+new Date().toLocaleString());
        Student stu =  studentService.getAllStu(id);
        return stu;
    }
}

Student

package com.demo.stuprovider.entity;

public class Student {

    private Integer id;
    private String name;
    private  Integer age;
    private  String password;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}


StudentMapper

package com.demo.stuprovider.mapper;

import com.demo.stuprovider.entity.Student;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface StudentMapper {
   public Student getAllStu(Integer id);
}

StudentService

package com.demo.stuprovider.service;

import com.demo.stuprovider.entity.Student;

public interface StudentService {
   public Student getAllStu(Integer id);
}

StudentServiceImpl

package com.demo.stuprovider.service.impl;

import com.demo.stuprovider.entity.Student;
import com.demo.stuprovider.mapper.StudentMapper;
import com.demo.stuprovider.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class StudentServiceImpl implements StudentService {

    @Resource
    private StudentMapper studentMapper;


    @Override
    public Student getAllStu(Integer id) {
        return studentMapper.getAllStu(id);
    }
}

Student.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.demo.stuprovider.mapper.StudentMapper">

    <select id="getAllStu" parameterType="java.lang.Integer"  resultType="com.demo.stuprovider.entity.Student">
        select  id,name,age,password from student where id = #{id}
    </select>


</mapper>

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <settings>
        <!-- 配置關閉緩存  -->
        <setting name="cacheEnabled" value="false"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <setting name="useGeneratedKeys" value="true"/>
        <setting name="defaultExecutorType" value="REUSE"/>
        <!-- 事務超時時間 -->
        <setting name="defaultStatementTimeout" value="600"/>
    </settings>

    <typeAliases>
        <package name="com.home.entity" />
        <!--<typeAlias type="Account" alias="user" />-->
    </typeAliases>
    <!--<mappers>
        <mapper resource="mapper/user.xml" />
    </mappers>-->
</configuration>

application.yml:

eureka:
  client:
    service-url:
      defaultZone: http://user:password123@localhost:8761/eureka
  instance:
      prefer-ip-address: true
      instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
      hostname: localhost
      ip-address: localhost
server:
  port: 7900
spring:
  application:
    name: stu-provider
  datasource:
      url: jdbc:mysql://10.167.199.44:3306/test?useSSL=false
      username: root
      password: ****
      driver-class-name: com.mysql.jdbc.Driver
      type: com.alibaba.druid.pool.DruidDataSource
      initialSize: 20
      minIdle: 50
      maxActive: 80
      maxWait: 10000
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMills: 300000
  thymeleaf:
    prefix: classpath:/templates/**
    suffix: .html
mybatis:
  config-location: classpath:/mybatis/mybatis-config.xml
  mapper-locations: classpath:/mapper/Student.xml

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.home</groupId>
    <artifactId>stu-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>stu-provider</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.1.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-solr</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.3.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.6</version>
        </dependency>

        <!-- 支持 @ConfigurationProperties 註解 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>

        <!--mybatis與mysql-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.2.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--druid依賴-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.25</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

結果如下:

這個時候我們的application的名稱和status的顯示都是很不清晰的,我們如過要讓它顯示的更加明白,可以更改yml的配置如下所示:

eureka:
  client:
    service-url:
      defaultZone: http://user:password123@localhost:8761/eureka
  instance:
    hostname: localhost
    ip-address: localhost
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}}

server:
  port: 7900
spring:
  application:
    name: stu-provider

這時候我們會看到eureka報了警告如下:

這個翻譯過來如下:

//緊急情況!Eureka可能錯誤地聲稱實例已經啓動,而事實並非如此。續約低於閾值,因此實例不會爲了安全而過期。

這個是eureka的自我保護機制,如果我們想關閉它的自我保護,可以加入如下的配置:

eureka:
  server:
    enable-self-preservation: false  #關閉自我保護
    eviction-interval-timer-in-ms: 60

服務消費者

新建項目stu-consumer:

ConsumerController

package com.consumer.stuconsumer.controller;

import com.consumer.stuconsumer.entity.Student;
import com.consumer.stuconsumer.feign.UserFeginClient;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

@RestController
@RequestMapping("/")
public class ConsumerController {

    @Resource
    private UserFeginClient userFeginClient;

    @RequestMapping("/getAll/{id}")
    public Student getAll(@PathVariable("id") Integer id) {
        Student stu = this.userFeginClient.getAll(id);
        System.out.println(stu);
        return stu;
    }

}

Student

package com.consumer.stuconsumer.entity;

public class Student {

    private Integer id;
    private String name;
    private  Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

HyStrixClientFactory

package com.consumer.stuconsumer.feign;

import feign.hystrix.FallbackFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class HyStrixClientFactory implements FallbackFactory<UserFeginClient> {

    private static final Logger log = LoggerFactory.getLogger(HyStrixClientFactory.class);

    @Override
    public UserFeginClient create(Throwable cause) {
        log.info("factory的返回異常信息打印:"+cause);
        return null;
    }
}

HyStrixFallBackClient

package com.consumer.stuconsumer.feign;

import com.consumer.stuconsumer.entity.Student;
import org.springframework.stereotype.Component;

@Component
public class HyStrixFallBackClient  implements UserFeginClient{
    @Override
    public Student getAll(Integer id) {
        return null;
    }
}

UserFeginClient

package com.consumer.stuconsumer.feign;

import com.consumer.stuconsumer.entity.Student;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient(name="stu-provider", fallback=HyStrixFallBackClient.class,fallbackFactory = HyStrixClientFactory.class)
public interface UserFeginClient {


    //不支持getmapping
    @RequestMapping("/getAll/{id}")
    public Student getAll(@PathVariable("id")Integer id);


}

StuConsumerApplication

package com.consumer.stuconsumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableCircuitBreaker
public class StuConsumerApplication {

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

application.yml:

server:
  port: 9301
eureka:
  client:
    healthcheck:
      enable: true
    serviceUrl:
      defaultZone: http://user:password123@localhost:8761/eureka
#      defaultZone: http://eureka1:8761/eureka,http://eureka2:8762/eureka,http://eureka3:8763/eureka
  instance:
    hostname: localhost
    ipAddress: localhost
    prefer-ip-address: true
    instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
spring:
  application:
    name: stu-consumer
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://10.167.199.44:3306/test?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=UTF-8;useSSL=false
    username: root
    password: ****
    type: com.alibaba.druid.pool.DruidDataSource
    initialSize: 5
    minIdle: 5
    maxActive: 30
    maxWait: 10000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMills: 300000
    validationQuery: SELECT 1 FROM DUAL
  session:
    store-type: none
#  redis:
#      host: 127.0.0.1
#      port: 6379
#      password: redis
#      database: 0
#    配置ribbon
#stu-provide:
#  ribbon:
#
##    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #配置規則 隨機
#    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #配置規則 輪詢
##    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RetryRule #配置規則 重試
##    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule #配置規則 響應時間權重
##    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.BestAvailableRule #配置規則 最空閒連接策略
#    ConnectTimeout: 500 #請求連接超時時間
#    ReadTimeout: 1000 #請求處理的超時時間
#    OkToRetryOnAllOperations: true #對所有請求都進行重試
#    MaxAutoRetriesNextServer: 2 #切換實例的重試次數
#    MaxAutoRetries: 1 #對當前實例的重試次數

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
feign:
  hystrix:
    enabled: true
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章