• Spring Cloud Eureka


     

    搭建服务注册中心

    创建eureka-center,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>org.mythsky</groupId>
        <artifactId>eureka-center</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>eureka-center</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.9.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <spring-cloud.version>Edgware.RELEASE</spring-cloud.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka-server</artifactId>
            </dependency>
            <!--<dependency>-->
                <!--<groupId>org.mybatis.spring.boot</groupId>-->
                <!--<artifactId>mybatis-spring-boot-starter</artifactId>-->
                <!--<version>1.3.1</version>-->
            <!--</dependency>-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    
    </project>
    View Code

    在Spring Boot启动类上添加@EnableEurekaServer

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

    编辑application.properties

    server.port=1111
    
    eureka.instance.hostname=localhost
    eureka.client.register-with-eureka=false
    eureka.client.fetch-registry=false
    eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
    
    eureka.server.enable-self-preservation=false

    eureka.client.register-with-eureka=false

    默认设置下,服务中心会将自己作为客户端来注册自己,所以这里配置为false

    eureka.client.fetch-registry=false

    禁用检索服务

    eureka.server.enable-self-preservation=false

    禁用Eureka Server的自我保护机制,Eureka Server在运行期间会统计心跳失败的比例在15分钟内是否低于85%,在单机调试时很容易满足,从而不能正常调用服务

    这里还需要注意一个设置,这个设置也是在自我保护机制关闭的情况下生效

    eureka.server.eviction-interval-timer-in-ms=5000

    这个设置是eureka server 每5秒钟剔除失效的服务,这个配合服务提供端的设置生效

    比如服务提供端有如下配置

    eureka.instance.lease-renewal-interval-in-seconds=10
    eureka.instance.lease-expiration-duration-in-seconds=15

    意思是服务提供端每10秒发送一次服务续约,服务的失效时间为15秒,即如果服务端下线,15秒后eureka server将其服务剔除,如果上面的主动剔除时间设为30秒,那么这里会在30秒后剔除服务

    还有一个服务消费端获取服务的设置

    eureka.client.registry-fetch-interval-seconds=10

    表示每10s获取一次服务列表

    如果在10s内服务提供端下线并重新上线,服务消费端还没有拉取最新服务地址,会出现连接超时报错

     

    继续将服务提供端下线,10s后消费端重新获取服务地址,此时再调用服务,会提示没有可用服务

    运行后访问:http://localhost:1111/,即可看到如下界面:

    这里的红色提示是因为我们上面的配置关闭了自我保护。

    高可用注册中心

    创建application-peer1.properties

    spring.application.name=eureka-server
    server.port=1111
    
    eureka.instance.hostname=peer1
    eureka.client.service-url.defaultZone=http://peer2:1112/eureka/

    创建application-peer2.properties

    spring.application.name=eureka-server
    server.port=1112
    
    eureka.instance.hostname=peer2
    eureka.client.service-url.defaultZone=http://peer1:1111/eureka/

    在host中添加转换

    127.0.0.1    peer1
    127.0.0.1    peer2

    通过spring.profiles.active 分别启动peer1 和peer2

    java -jar eureka-center-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
    java -jar eureka-center-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2

    这里要注意,在application-peer2.properties中没配置但在application.properties中有配置的话依旧会读取application.properties中的内容

    还需要注意的是eureka.instance.prefer-ip-address=true这个配置,在这个配置下eureka.client.service-url.defaultZone=http://${spring.security.user.name}:${spring.security.user.password}@172.26.10.110:8090/eureka/

    这里可以用IP+port,此时可以不设置eureka.instance.hostname

    如果eureka.instance.prefer-ip-address=false,eureka.client.service-url.defaultZone里面可以用域名yourdomain:8090/eureka,此时必须设置eureka.instance.hostname=yourdomain

    从下面的界面即可看到

    打开http://localhost:1111/

     打开http://localhost:1112/

     这里可以看到replicas都是不可用的

    修复上面的问题,正确结果应该如下

    这里还有两个重要属性

    eureka.instance.lease-renewal-interval-in-seconds=30
    eureka.instance.lease-expiration-duration-in-seconds=90

    第一个用于定义服务续约任务的调用时间,默认30秒

    第二个用于定义服务失效的时间,默认90秒

     服务提供者

    新建一个Spring Boot项目,添加pom依赖

    <?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.example</groupId>
        <artifactId>demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>demo</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.9.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <spring-cloud.version>Edgware.RELEASE</spring-cloud.version>
        </properties>
    
        <dependencies>
            <!--<dependency>-->
                <!--<groupId>org.mybatis.spring.boot</groupId>-->
                <!--<artifactId>mybatis-spring-boot-starter</artifactId>-->
                <!--<version>1.3.1</version>-->
            <!--</dependency>-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    
    </project>
    View Code

    在入口添加@EnableDiscoveryClient

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

    添加一个控制器

    @RestController
    public class HelloController {
        private  final Logger logger=Logger.getLogger(String.valueOf(getClass()));
        @Autowired
        private DiscoveryClient client;
        @RequestMapping(value = "/hello",method = RequestMethod.GET)
        public String index(){
            ServiceInstance instance=client.getLocalServiceInstance();
            logger.info("/hello,host:"+instance.getHost()+", service_id:"+instance.getServiceId());
            return "hello world";
        }
    }

    新版接口中无法使用client.getLocalServiceInstance()

    更改如下

            String serviceId=client.getServices().get(0);
            ServiceInstance instance=client.getInstances(serviceId).get(0);

    在配置中应用服务名称及服务中心地址

    server.port=8080
    management.security.enabled=false
    spring.application.name=hello-service
    eureka.client.service-url.defaultZone=http://localhost:1111/eureka/,http://localhost:1112/eureka/

    启动服务,在Eureka界面即可看到注册的服务

     同时在控制台中可以看到日志

    在Idea中点击Exit

    可以看到服务立刻下线

    如果是点击上面的Stop,并不能立刻看到服务下线,而是等到上面的轮询时间才能看到。

    服务发现和消费

    新建Spring Boot项目,取名为ribbon-consumer,pom如下

    <?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>org.mythsky</groupId>
        <artifactId>ribbon-consumer</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>ribbon-consumer</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.9.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <spring-cloud.version>Edgware.RELEASE</spring-cloud.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-ribbon</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    
    </project>
    View Code

    应用入口处添加@EnableDiscoveryClient和@LoadBalanced开启客户端负载均衡

    @EnableDiscoveryClient
    @SpringBootApplication
    public class RibbonConsumerApplication {
    
        @Bean
        @LoadBalanced
        RestTemplate restTemplate(){
            return new RestTemplate();
        }
    
        public static void main(String[] args) {
            SpringApplication.run(RibbonConsumerApplication.class, args);
        }
    }

    添加控制器

    @RestController
    public class ConsumerController {
        @Autowired
        RestTemplate restTemplate;
        @RequestMapping(value = "/ribbon-consumer",method = RequestMethod.GET)
        public String helloConsumer(){
            return restTemplate.getForEntity("http://hello-service/hello",String.class).getBody();
        }
    }

    修改配置

    spring.application.name=ribbon-consumer
    server.port=9000
    
    eureka.client.service-url.defaultZone=http://localhost:1111/eureka/

    启动应用,访问http://localhost:9000/ribbon-consumer,会看到返回了服务提供的信息

    此时在Eureka界面可以看到

    多次刷新消费页面,观察两个注册中心的日志,可以看到两个中心轮流提供服务

    启用安全认证

    在注册中心启用security

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

    配置

    spring.security.user.name=user
    spring.security.user.password=pwd123
    eureka.client.service-url.defaultZone=http://${spring.security.user.name}:${spring.security.user.password}@${eureka.instance.hostname}:${server.port}/eureka/

    由于spring默认开启csrf,所以做如下修改

    @Configuration
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable();
            super.configure(http);
        }
    }

    服务提供者配置

    service.username=user
    service.password=pwd123
    eureka.client.service-url.defaultZone=http://${service.username}:${service.password}@localhost:1111/eureka/

    这样就能实现安全认证了。

     

  • 相关阅读:
    paip.提升用户体验上传文件图片命名
    paip.提升安全性软键盘的弱点
    paip.java桌面开发应用与WEB RIA应用
    paip.提升安全性WEB程序安全检测与防范
    paip.PHP zend解密—以SHOPEX4.8.4为例
    PAIP.提升安全性COOKIE绑定IP与城市与运营商
    paip.svn不能提交CLEARUP不起作用解决方法
    paip.提升安全网站登录密码明文传输的登录高危漏洞解决方案
    paip.docfile二进制复合文档
    paip.session的调试in php
  • 原文地址:https://www.cnblogs.com/uptothesky/p/8086414.html
Copyright © 2020-2023  润新知