JAVA服务器开发

分布式系统开发---高可用业务服务器SpringCloud(五)

2019-01-04  本文已影响14人  Felix_

本节我们将把我们的项目改造成一个高可用的业务服务器,这里使用SpringCloud中的Eureka,首先,我们来认识下Eureka

Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。

针对我们之前做好的服务分离实例,遗留了一个问题,那就是如果我新增了一个服务,或者商品服务的服务端IP或者域名改变了,是不是我还要再次修改订单服务中获取商品信息的逻辑(IP地址)来达到我们的目的,但是随之而来的就是各种配置。

上面介绍了Eureka的功能,最终实现后的应用场景就是我们不用再关心商品服务服务器的IP地址或域名,只需要从Eureka中注册的各种服务中找到商品服务,从中获取我们需要的数据即可,下面,我们来编写Eureka这个服务中心。

在我们的项目中创建新的模块eureka,这里要注意下,我们这次在选择依赖的时候选择Cloud Discovery,勾选Eureka Server如图:


创建好的eureka模块如图

这里,我们把eureka中的application.properties修改为application.yml,同时指定服务端的端口号为7000

注:为了避免以后的端口冲突,我们把order的端口从8001改变成8100


接下来回到eureka模块中,修改eureka模块中的EurekaApplication代码如下
package com.felix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }

}

配置eureka模块中的application.yml

server:
  port: 7000
eureka:
  client:
    register-with-eureka: false #是否注册到Eureka服务中
    fetch-registry: false #是否从Eureka服务中获取注册信息
    service-url: #Eureka客户端与服务端进行交互的地址
      defaultZone: http://127.0.0.1:${server.port}/eureka/

到了这里,我们的服务中心已经搭建完毕,启动eureka服务器后访问http://127.0.0.1:7000就会看到如下界面


当然,出于安全性考虑,这个界面一定不能任何人都可以访问,所以,我们需要添加用户认证。在eurekapom.xml添加spring-boot-starer-security依赖
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starer-security</artifactId>
        </dependency>

修改配置文件application.yml,设置eureka页面的用户名和密码,同时修改默认的service-url:

server:
  port: 7000

spring:
  security:
    user:
      name: felix
      password: 123456

eureka:
  client:
    register-with-eureka: false #是否注册到Eureka服务中
    fetch-registry: false #是否从Eureka服务中获取注册信息
    service-url: #Eureka客户端与服务端进行交互的地址
      defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@127.0.0.1:7000/eureka/

然后在程序入口启用安全认证,EurekaApplication修改如下

package com.felix;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {

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

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

重新启动eureka服务,这次会弹出登录窗口,我们填写之前设置的用户名和密码后就可以顺利登录了


登录后,因为没有服务注册到服务中心,所以Instances currently registered with Eureka中的内容为空。我们需要订单服务商品服务中获取商品信息,所以,需要把商品服务注册到服务中心去,同时订单服务需要从服务中心中发现服务,并且使用,所以,下一步,我们开始注册商品服务服务中心
修改goods模块的pom.xml,添加Eureka的依赖
<?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.felix</groupId>
    <artifactId>goods</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>goods</name>
    <description>A service of goods for mall</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.RC2</spring-cloud.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</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>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>
</project>

然后修改goods中的配置文件application.yml

server:
  port: 8000

spring:
  application:
    name: goods-service #指定服务名称

eureka:
  client:
    register-with-eureka: true #是否注册到Eureka服务中
    fetch-registry: false #是否从Eureka服务中获取注册信息
    service-url: #Eureka客户端与服务端进行交互的地址
      defaultZone: http://felix:123456@127.0.0.1:7000/eureka/
  instance:
    prefer-ip-address: true #把ip地址注册到Eureka服务中

这里,我们指定商品服务的服务名为goods-service,然后配置Eureka,因为商品服务需要注册到服务中心,所以register-with-eureka设置为true
现在,我们启动商品服务(没有启动服务中心的也要启动服务中心),等到启动完毕后,再次访问http://127.0.0.1:7000/页面如下


可以看到,商品服务的服务名称goods-service已经成功注册到服务中心了(显示的是大写)
接下来我们来改造订单服务,让它从服务中心发现服务,利用发现的服务请求对应的数据。首先,和商品服务类似,我们先修改order模块的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>
    <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.felix</groupId>
    <artifactId>order</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>order</name>
    <description>A service of order for mall</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.RC2</spring-cloud.version>
    </properties>

    <dependencies>

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

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <exclusions>
                <exclusion>
                    <!--排除Eureka自带的数据格式转换,否则返回的结果会被转成XML格式的数据-->
                    <groupId>com.fasterxml.jackson.dataformat</groupId>
                    <artifactId>jackson-dataformat-xml</artifactId>
                </exclusion>
            </exclusions>
        </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>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>
</project>

这里一定要在Eureka依赖中排除<groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId>否则订单信息的返回结果将会被转换成XML格式。
添加好依赖以后,我们修改订单服务中的配置文件application.yml

server:
  port: 8100
  #port: 8001

spring:
  application:
    name: order-service #指定服务名称

eureka:
  client:
    register-with-eureka: false #是否注册到Eureka服务中
    fetch-registry: true #是否从Eureka服务中获取注册信息
    service-url: #Eureka客户端与服务端进行交互的地址
      defaultZone: http://felix:123456@127.0.0.1:7000/eureka/

这里,订单服务无需注册到服务中心,但是需要从服务中心获取注册的服务信息,所以上面的配置需要按照我们的需求进行调整。
最后,修改OrderApplication中的代码

package com.felix;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableDiscoveryClient
@SpringBootApplication
public class OrderApplication {

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

}

大功告成,我们启动订单服务(确认商品服务服务中心都已经启动),然后访问订单服务的接口http://127.0.0.1:8100/order/6,结果如下


现在,我们已经有了三台服务端了商品服务订单服务服务中心,为了展示目前的效果,我们再启动一个商品服务。首先我们修改goods中的application.yml的端口号为8081,然后点击顶部的模块选择,点击Eidt Configurations

在弹出的窗口中点击加号,选择Spring Boot

依次修改名称为GoodsApplication01MainClass选择GoodsApplicationUse classpath of module选择goods,点击Apply后选择OK完成

然后,在顶部选择刚才创建的GoodsApplication01并启动,现在,我们可以看到,已经启动了四个服务:

等到启动完成后,GoodsApplication01会在服务中心注册一个新的商品服务,我们现在打开http://127.0.0.1:7000/会发现服务中心已经有两个注册的服务了,此时访问订单服务,一切正常
现在,我们模拟单台服务故障,我们手动关闭GoodsApplication01

现在,再次访问订单服务仍然没有问题,实际上,提供商品服务的一台服务器已经故障了,我们看下Eureka界面


注册的服务中也只剩下一个了,但是并没有影响我们的业务访问。
截止目前,我们已经初步搭建了一个分布式系统了,实现了业务服务器的高可用,系统中提供业务的某台服务器即使Down机,也不会影响我们业务的正常访问。

结束之前,留下一个问题,虽然业务服务器达到了高可用,但是,它是基于服务中心的,那么如果服务中心Down掉了,岂不是仍然会影响业务吗?是的,下节我们就来解决这个问题。
分布式系统开发---高可用服务中心SpringCloud(六)
以上内容转载请注明出处,同时也请大家不吝你的关注和下面的赞赏
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

上一篇 下一篇

猜你喜欢

热点阅读