服务器系统总崩溃?来试试分布式部署

SpringCloud分布式

Posted by LY on November 30, 2018

喜欢我文章的同学们可以关注我的今日头条百家号简书个人博客CSDN

前言

1.之前有人给我留言说想要了解一下分布式,今天呢,我们就来简单的说一下SpringCloud分布式并且实现一个简单的demo。

2.最近更新变少了,因为工作中也没有遇到什么有意思的知识点,希望大家可以提供一些想要了解的知识,私信或者评论都可以。

我理解的SpringCloud

1.首先,我们的分布式系统都需要有一个服务注册中心,来将所有提供服务的系统都注册到系统中。在我了解的两种分布式框架:Double(阿里)、SpringCloud(Spring),在这两种里面,我选择了Spring。我认为SpringCloud更加简捷方便一些。

2.其次,有了注册中心,那我们就需要有服务的提供者,也就是我们所说的微服务,只需要在项目中加入几个简单的配置,就可以将服务注册到注册中心,供其他客户端使用。

3.最后呢,我们还需要注册消费者,通过消费者来消费注册中心中的服务接口。

SpringCloud代码实现

一、SpringCloud服务注册中心

1.使用IntelliJ IDEA或者是其他的Java IDE创建一个Springboot项目,命名为eureka-server,当然这个自由选择哈。

2.等待MAVEN构建好项目之后,打开pom.xml进行配置,并添加如下依赖。

    <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>Finchley.SR1</spring-cloud.version>
    </properties>
    <dependencies>
        <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>

3.打开主类,也就是启动类,添加如下注解,将该项目注册为服务注册中心

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

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

4.打开项目中的application.properties我会将其重命名为application.yml,其实两种格式并没有什么分别,只是个人喜好而已。

5.修改application.yml配置,如下。

# 端口号
server:
  port: 8768
# 注册中心配置
eureka:
  instance:
    hostname: 你的IP地址或者主机名或者是localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

spring:
  application:
    name: eurka-server

6.它的配置还有很多,比如

eureka.server.enable-self-preservation			# 设为false,关闭自我保护
eureka.server.eviction-interval-timer-in-ms     # 清理间隔(单位毫秒,默认是60*1000)

配置有很多,大家可以去官方文档查看一下,按需配置。

7.自此注册中心算是配置完善,启动项目后,访问对应端口即可看到如下页面。

屏幕快照 2018-11-30 上午11.38.01

二、SpringCloud服务提供者

1.同上创建Springboot项目,选择创建为WEB项目,名为service-test可以选择常用的持久化框架mybatis、JAP等等,选择数据库驱动。当然持久化框架可以不选,待MAVEN构建好项目之后可以手动加入自己的持久化,比如我常用的mybatis-plus或者hibernate、JDBC等等。

屏幕快照 2018-11-30 下午1.54.02

2.打开pom.xml添加依赖

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

3.打开启动类,添加注释@EnableEurekaClient注册成为服务提供者。

4.配置application.yml

server:
  port: 8888

spring:
  application:
    name: service-test
eureka:
  client:
    serviceUrl:
      defaultZone: http://你的服务注册中心地址:端口/eureka/
  instance:
    hostname: 服务提供者地址,及当前项目service-test所在ip

5.启动项目后,可以在服务注册中心的日志中看到如下结果:

屏幕快照 2018-11-30 下午2.05.00

Registered instance SERVICE-TEST/192.168.12.18:service-test:8888 with status UP (replication=false)

也可以在浏览器打开服务注册中心查看服务是否注册成功:

屏幕快照 2018-11-30 下午2.06.34

6.如上即为可提供服务,接下来就可以编写我们的服务代码,这里我们简单的以返回字符串为例子。TestController

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class TestController {
    @RequestMapping("/testOne")
    public String testOne() {
        return "成功进入";
    }
}
三、SpringCloud服务消费

1.由上面的Java代码可以看出,我们的service-test服务者提供了一个/test/testOne的服务,那我们接下来就来创建一个消费者来消费该服务。

2.依旧创建Springboot项目,命名为consumer添加同上依赖,在application.yml中添加如下配置

eureka:
  client:
    serviceUrl:
      defaultZone: http://注册中心地址:端口/eureka/
  instance:
    hostname: 当前IP
server:
  port: 端口
spring:
  application:
    name: consumer

3.在启动类中添加如下注解,注册为消费者。

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.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients
public class ConsumerApplication {

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

4.编写ConsumerService.java接口,以此消费我们service-test中提供的服务。代码如下:


import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Service
// 从服务注册中心中通过名称查找服务
@FeignClient(value = "service-test")
public interface ConsumerService {
    // 消费该服务提供者提供的“/test/testOne”服务
    @RequestMapping(value = "/test/testOne", method = RequestMethod.GET)
    String testOne();
}

5.编写ConsumerController.java

@RestController
public class ConsumerController {
    @Autowired
    private TestService testService;
    @GetMapping("/test")
    public String test() {
        return testService.testOne();
    }
}

6.启动项目后同样可以在服务注册中心的控制台以及页面查看注册信息。

7.查看到服务注册成功之后,我们正常访问,localhost:端口/test。就可以看到页面会返回成功进入的字样,即代表我们的服务消费成功。

屏幕快照 2018-11-30 下午2.32.30

四、SpringCloud分布式服务器部署测试

1.正好手头有不少服务器,我们来部署测试一下,是否实现了简单的分布式。

2.首先将我们的三个项目打包为jar文件上传至服务器当中。具体操作如下

屏幕快照 2018-11-30 下午2.36.53

3.待命令执行完后,可以在项目的target目录中看到生成的jar文件。

4.通过scp命令将jar包上传至服务器目录

scp -r 文件本地路径 服务器用户名@服务器ip:/home/用户名

5.接下来就是启动jar包

# nohup 为后台执行,如果不使用该命令,当关闭终端或者断开链接时,jar也会停止运行,导致项目无法访问
nohup java -Dserver.port=部署端口 -jar 文件名

6.待项目全部部署完毕,我们先来看一下服务注册中心。

屏幕快照 2018-11-30 下午2.44.29

可以看到两个服务均注册成功,我们运行看一下。

屏幕快照 2018-11-30 下午2.45.30

与本地运行相同,但我们的三个项目时部署到不同的服务器当中的,以此也就实现了简单的分布式部署。

五、SpringCloud、Ribbon开启负载均衡

1.我们需要启动同一个服务两次,在不同的端口或者是服务器。

2.项目启动后可以在注册中心看到同名为service-test的服务有两个。

3.在消费者的主类中添加如下代码开启负载均衡。

	@Bean
	@LoadBalanced
	RestTemplate restTemplate() {
		return new RestTemplate();
	}

4.这样,他会根据访问的次序,自动的将用户分配到不同的服务器或者端口。

最后说几句

1.当然这只是最基础的一部分。我也还在不断的学习和深入了解当中。

2.至于这样部署的好处嘛,不仅减轻了服务器的负担,同样降低了耦合,如果我们只是下线一部分功能或者对功能进行升级,不会对整体造成影响。

3.感谢大家的关注和支持,希望大家多多提出意见。

4.我在自己的服务器当中搭建了GitLab服务器,使用后感觉也是非常不错,如果有想要尝试自己搭建或者使用我搭建好的可以私信或者评论告诉我。

5.谢谢大家🙏🙏🙏