SpringCloud 分布式微服务框架

 

SpringCloud讲义

微服务管理框架

 

  

1 Spring Cloud概述 4

1.1 基于SOA系统架构 4

1.2 Spring Cloud的作用 5

1.3 为什么要学习Springcloud 6

1.4 如何学习SpringCloud 6

2 入门示例 6

2.1 配置步骤 6

2.2 第一部分:配置Eureka服务器(注册中心) 6

2.2.1 第一步:创建一个maven项目 7

2.2.2 第二步:在Spring官方网站,生成代码 7

2.2.3 第三步:创建一个启动类Application 9

2.2.4 第四步:创建配置文件application.properties 10

2.2.5 第五步:启动程序测试 10

2.3 第二部分:创建一个注册服务实例instanceServer 11

2.3.1 第一步:创建一个Maven项目 11

2.3.2 第二步:生成Spring boot项目代码 11

2.3.3 第三步:编写Application入口类 13

2.3.4 第四步编写一个Controller 14

2.3.5 第五步:编写配置文件application.properties 14

2.3.6 第六步:启动实例 15

2.4 第三部分:创建一个发现服务实例新实例(调用服务) 16

2.4.1 第一步:修改pom.xml配置文件的项目名 16

2.4.2 第二步:修改appplication.properties配置文件 16

2.4.3 第三步:修改发现服务入门程序注解 17

2.4.4 第四步:启动实例 17

2.5 第四部分:实现instanceClientinstanceServer的远程调用 17

2.5.1 第一步:修改注册服务,注册login登陆服务 18

2.5.2 第二步:修改发现服务实例instanceClient 19

2.5.3 第三步:启动实例 21

2.5.4 第四步:基于ribbon负载均衡实现 22

3 基于Feign实现服务调用 24

3.1 第一步:添加Feign依赖 24

3.2 第二步:修改UserService 24

3.3 第三步:修改启动类Application 25

3.4 第四步:启动instanceClient2 25

4 Eureka高可用配置 26

4.1 入门示例存在的缺陷 26

4.2 配置步骤 26

4.3 第一步:配置一个Eureka服务器。(已实现) 26

4.4 第二步:复制另外一个Eureka服务器 26

4.4.1 修改pom.xml中的Eureka服务名 27

4.4.2 修改application.properties配置文件 27

4.5 第三步:配置两个Eureka高可用(通讯) 28

4.5.1 修改第一个Eurekaapplication.properties文件 28

4.5.2 修改第二个Eurekaapplication.properties文件 28

4.5.3 修改本地hosts文件注册Eureka主机名 29

4.6 第四步:分别启动两个Eureka测试 29

4.7 第五步:测试Eureka高可用 30

4.7.1 修改实例instanceServerapplication.properties文件 30

4.7.2 修改实例instanceClientapplication.properties文件 31

4.7.3 修改实例instanceServer2application.properties文件 31

4.7.4 依次启动这三个实例 31

4.7.5 测试实例2调用远程服务 32

4.7.6 测试Eureka高可用 32

5 Eureka安全认证 33

5.1 第一部分:在Eureka服务端开启身份认证 33

5.1.1 第一步添加身份认证依赖 33

5.1.2 第二步:开启身份认证 33

5.2 第二部分:在Eureka客户端进行身份认证 34

6 SpringBoot项目打包发布 34

6.1 第一步:使用Maven打包 34

6.2 第二步上传到Linux环境 35

6.3 第三步编写启动文件 35

7 改造电商系统为springcloud分布式架构 36

7.1 第一步改造ego-projectspringcloud系统 36

7.2 第二步:改造ego-order系统为注册服务实例系统 42

7.3 第三步:改造ego-portal工程为发现服务实例系统 45


Spring Cloud概述

1.1 基于SOA系统架构

面向服务的架构,是一种程序开发架构的设计思想。它将不同的功能单元使用一个作为独立的程序运行,并且提供访问的入口(将这些单独运行的每个程序称为服务)。

一个SOA架构的web应用程序,是多个服务组成的!!!

SOA架构的思想就是用于实现,程序分布式的。所以我们也可以将SOA架构的思想理解为分布式架构的思想。

如图所示:

 

1.2 Spring Cloud的作用

问题以上SOA架构这样的系统架构有什么问题

答:(1)无法检查服务的健康状态(服务是否可用)。

   2)无法对服务进行管理。

我们可以通过一个框架来,解决这些问题。那就是Spring Cloud

Spring Cloud通过一个注册中心(Eureka),统一管理了整个分布式系统的服务接口。

 

所有的服务(子系统)在对外提供服务(接口)之前,必须要在注册中心中注册。我们开发人员就可以在注册中心中,查看整个分布式系统的所有服务!!

我们SOA概念中称为服务系统的东西,在Spring cloud有一个新的名字,叫实例(instance,实例系统)!

1.3 为什么要学习Springcloud

Springcloud是提供了一整套企业级分布式云应用的完美解决方案,能够结合Spring BootSpring其它组件,实现快速开发的目的

企业级开发越来越倾向Spring生态体系。当然也包括SpringCloud了。

1.4 如何学习SpringCloud

根据上图所示,我们学习Spring Cloud首先要学习什么东西呢?

答:(1)必须要将Eureka配置成功

   2)实例是如何将服务在Eureka注册的

   3)如何在Eureka查看整个分布式系统所有实例对外提供的服务(发现服务)

   4)实例域实例之间是如何通讯的(远程调用)

    

入门示例

2.1 配置步骤

第一步:配置Eureka服务器

第二步:创建注册服务实例(Eureka客户端-注册服务@EnableEurekaClient)

第三步:创建发现服务实例(Eureka客户端-发现服务@EnableDiscoveryClient)

第四步:实现发现服务实例调用注册服务实例的示例。

 

2.2 第一部分:配置Eureka服务器(注册中心)

--注意实现

1.Eclipse配置Spring Cloud必须先安装好 spring tool suite 插件。否则配置文件没有提示!!

2.Spring Cloud框架的jar都是由maven或者gradle构建工具获得的。我们主流使用的是Maven。所以创建的maven项目

2.2.1 第一步:创建一个maven项目

 

2.2.2 第二步:在Spring官方网站,生成代码

地址为:https://start.spring.io/

注意事项:必须要勾上Eureka Server选项

 

--生成代码包如下

 

我们需要将生成好的代码的pom.xml文件的依赖加入到我们的项目!!!!!

<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>cn.gzsxt.springcloud</groupId>

  <artifactId>springcloud-demo-01-eureka</artifactId>

  <version>1.0</version>

  

  <parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>1.5.19.RELEASE</version>

<relativePath/> <!-- lookup parent from repository -->

</parent>

<properties>

<java.version>1.8</java.version>

<spring-cloud.version>Edgware.SR5</spring-cloud.version>

</properties>

<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-eureka-server</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

</dependencies>

<dependencyManagement>

<dependencies>

<!-- springcloud版本锁定 -->

<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>

2.2.3 第三步:创建一个启动类Application

package cn.gzsxt.springcloud;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication

@EnableEurekaServer

public class EurekaApplication {

public static void main(String[] args) {

SpringApplication.run(EurekaApplication.class, args);

}

}

2.2.4 第四步:创建配置文件application.properties

#1.配置端口

server.port=5121

#2.配置eureka主机名,找到eureka所在的机器

eureka.instance.hostname=localhost

#3.是否将自身注册为服务 false表示不注册

eureka.client.register-with-eureka=false

#4.是否主动发现服务  false表示不发现

eureka.client.fetch-registry=false

#5.对外提供的注册入口

eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/

 

2.2.5 第五步:启动程序测试

 

--测试结果

 

2.3 第二部分:创建一个注册服务实例instanceServer

注意事项:实例使用的是Spring Boot

2.3.1 第一步:创建一个Maven项目

 

2.3.2 第二步:生成Spring boot项目代码

--注意实现:必须添加webmvc模块以及Eureka客户端模块

 

 

--将生成的项目的pom.xml代码覆盖项目的pom.xml

<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>cn.gzsxt.springcloud</groupId>

  <artifactId>springcloud-demo-02-instanceServer01</artifactId>

  <version>1.0</version>

  

  <parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>1.5.19.RELEASE</version>

<relativePath/> <!-- lookup parent from repository -->

</parent>

<properties>

<java.version>1.8</java.version>

<spring-cloud.version>Edgware.SR5</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-client</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>

2.3.3 第三步:编写Application入口类

 

--Application代码

package cn.gzsxt.springcloud;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication

@EnableEurekaClient

public class InstanceApplication {

public static void main(String[] args) {

SpringApplication.run(InstanceApplication.class, args);

}

}

2.3.4 第四步编写一个Controller

package cn.gzsxt.springcloud.controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@RestController

public class UserController {

@RequestMapping("/say")

public String say(){

 

return "hello,springcloud";

 

}

}

2.3.5 第五步:编写配置文件application.properties

#指定实例端口

server.port=8080

#指定实例名,springcloud是通过实例名称来寻址服务的

spring.application.name=instanceServer

#指定Eureka服务端访问路径

eureka.client.service-url.defaultZone=http://localhost:5121/eureka

2.3.6 第六步:启动实例

--注意事项:因为实例是Eureka的客户端,所以启动实例之前,必须要先启动Eureka服务端!

2.3.6.1 启动Eureka服务端

--启动Eureka服务端,启动成功,会暴露配置文件指定的5121端口

 

--测试Eureka服务端是否成功在浏览器输入http://localhost:5121

如果成功,会出现以下页面

 

2.3.6.2 启动注册服务实例instanceServer01

--启动成功,会暴露配置文件指定的8080端口

 

--通过Eureka服务端管理后台可以查看客户端服务是否注册成功

 

2.4 第三部分:创建一个发现服务实例新实例(调用服务)

说明:将实例1复制一份。修改配置文件,修改为第二个实例

2.4.1 第一步:修改pom.xml配置文件的项目名

 

2.4.2 第二步:修改appplication.properties配置文件

#指定实例端口

server.port=8081

#指定实例名,springcloud是通过实例名称来寻址服务的

spring.application.name=instanceClient

#指定Eureka服务端访问路径

eureka.client.service-url.defaultZone=http://localhost:5121/eureka

2.4.3 第三步:修改发现服务入门程序注解

@SpringBootApplication

//标记该项目为一个,该实例是一个发现服务的实例

@EnableDiscoveryClient

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

2.4.4 第四步:启动实例

启动实例2,确定实例在Eureka服务端注册时成功的。

--如果启动成功,会暴露一个application.xml配置文件指定的访问端口8081

 

2.5 第四部分:实现instanceClientinstanceServer的远程调用

需求:

1)在instanceServer中,我们暴露一个login的远程restful接口。

2instanceClient调用该接口。将数据传递给它。

说明:SpringCloud远程服务调用,有两种实现方式:

1Ribbon+RestTemplate基于restful实现

其中,Ribbon是一个基于HTTPTCP客户端的负载均衡器

2Feign

      其中,Feign默认启动Ribbon负载均衡。

步骤说明:(1)修改注册服务代码

         2)修改发现服务代码

         3)启动实例,实现服务调用

         4)负载均衡实现。

2.5.1 第一步:修改注册服务,注册login登陆服务

1)创建User

package cn.gzsxt.instance.pojo;

import java.io.Serializable;

public class User implements Serializable{

/**

 *

 */

private static final long serialVersionUID = 7260598142983180828L;

private Integer id;

private String username;

private String password;

//补全getset方法

}

2)修改UserController类,新增登录方法

package cn.gzsxt.instance.controller;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import cn.gzsxt.instance.pojo.User;

@RestController

public class UserController {

/**

 * 用户登录 

 * @return

 */

@RequestMapping(value="/login",method=RequestMethod.POST)

public String login(@RequestBody User user){

System.out.println("用户名:"+user.getUsername()+",密码:"+user.getPassword());

return "Ok—intanceServer--8080";

}

}

2.5.2 第二步:修改发现服务实例instanceClient

1)添加Ribbon依赖

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-ribbon</artifactId>

</dependency>

2)修改Application启动类,标记该实例是发现服务实例

//1.用于启动Spring boot项目

@SpringBootApplication

//2.用于标识该项目是一个Eureka客户端(发现服务)

@EnableDiscoveryClient

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

    //2.创建RestTemplate实例对象,用来远程调用服务

@Bean

@LoadBalanced

public RestTemplate restTemplate(){

return new RestTemplate();

}

}

3)创建UserService

package cn.gzsxt.instance.service;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.web.client.RestTemplate;

import cn.gzsxt.instance.pojo.User;

@Service

public class UserService {

@Autowired

private RestTemplate restTemplate;

public String login(User user){

String result = restTemplate.postForObject("http://instanceServer/login",user, String.class);

return result;

}

}

4)修改UserController

package cn.gzsxt.instance.controller;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import cn.gzsxt.instance.pojo.User;

import cn.gzsxt.instance.service.UserService;

@RestController

public class UserController {

@Autowired

private UserService userService;

@RequestMapping("/login")

public String login(User user){

String result = userService.login(user);

System.out.println(result);

return result;

}

}

2.5.3 第三步:启动实例

说明:依次启动注册中心、服务提供实例、服务发现实例。

1)启动注册中心

 

2)启动服务提供者

 

4)启动服务发现者

 

5)访问注册中心 http://localhost:5121/eureka

 

6)访问服务发现实例

http://localhost:8081/login?username=root&password=123

 

远程服务调用成功!!!

2.5.4 第四步:基于ribbon负载均衡实现

负载均衡概念:在多个并且相同的服务可用的情况下,通过一定的负载策略,均衡的去调用这些服务,让服务到达一个平衡的状态。

重用的负载策略:轮询、权重、一致性ip等。

基于ribbon负载均衡实现步骤

1)创建一个新的注册服务实现instanceServer2。(复制instanceServer即可)

 

2)修改instanceServer2maven坐标

<groupId>cn.gzsxt.springcloud</groupId>

  <artifactId>springcloud-demo-04-instanceServer2</artifactId>

  <version>1.0</version>

3)修改application.properties文件

说明:相同的服务,实例的名称也相同。

    因此只用修改端口即可。

#指定实例端口

server.port=8082

#指定实例名

spring.application.name=instanceServer

#指定Eureka服务端访问路径

eureka.client.service-url.defaultZone=http://localhost:5121/eureka

4)修改UserController代码

@RequestMapping(value="/login",method=RequestMethod.POST)

public String login(@RequestBody User user){

System.out.println("用户名:"+user.getUsername()+",密码:"+user.getPassword());

return "Ok—intanceServer02--8082";

}

5)启动实例

 

6)多次访问登陆接口,查看结果

--调用到注册服务实例1

 

--调用到注册服务实例2

 

基于ribbon负载均衡实现!!!

基于Feign实现服务调用

说明在入门示例的基础上,复制一个新的发现服务实例instanceClient2

步骤说明:(1)添加Feign客户端依赖

         2)修改服务发现代码

3.1 第一步:添加Feign依赖

修改pom.xml文件

<!-- 注意事项:必须要导入该包 -->

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-feign</artifactId>

</dependency>

3.2 第二步:修改UserService

说明:Feign是基于interface接口来发现服务的。

package cn.gzsxt.instance.service;

import org.springframework.cloud.netflix.feign.FeignClient;

import org.springframework.web.bind.annotation.RequestMapping;

import cn.gzsxt.instance.pojo.User;

@FeignClient(name="instanceServer")

public interface UserService {

@RequestMapping(value="/login")

public String login(User user);

 

}

3.3 第三步:修改启动类Application

说明:添加Feign客户端支持  @EnableFeignClients

package cn.gzsxt.instance;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

import org.springframework.cloud.netflix.feign.EnableFeignClients;

//1.用于启动Spring boot项目

@SpringBootApplication  

//2.用于标识该项目是一个Eureka客户端(发现服务)

@EnableDiscoveryClient

@EnableFeignClients

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

3.4 第四步:启动instanceClient2

--调用到注册服务实例1

 

--调用到注册服务实例2

 

基于Feign远程访问成功!!!

Eureka高可用配置

4.1 入门示例存在的缺陷

在入门示例中,服务的注册、发现和调用,都是基于Eureka注册中心实现。

如果Eureka服务宕机了,整个服务就都不可用了。

解决的办法:

配置Eureka高可用,即配置多个Eureka服务器,当只要有一个Eureka还正常运行,就能够提供正常的服务。

4.2 配置步骤

第一步:先配置一个完整的Eureka服务器。

第二步:复制另外一个Eureka服务器。

第三步:修改两个Eureka的配置,实现这两个Eureka高可用。

4.3 第一步:配置一个Eureka服务器。(已实现)

4.4 第二步:复制另外一个Eureka服务器

--第一个Eureka服务器复制一份,修改器配置为第二个Eureka服务。

 

4.4.1 修改pom.xml中的Eureka服务名

<groupId>cn.gzsxt.springcloud</groupId>

<artifactId>springcloud-demo-01-eureka2</artifactId>

<version>1.0</version>

4.4.2 修改application.properties配置文件

--修改第二个Eureka的服务端口,不要和第一个冲突。

#1.配置端口

server.port=5122

#2.配置eureka主机名

eureka.instance.hostname=localhost

#3.由于我们目前创建的应用是一个服务注册中心,而不是普通的应用,默认情况下,这个应用会向注册中心(也是它自己)注册它自己,设置为false表示禁止这种默认行为

eureka.client.register-with-eureka=false

#4.表示不去检索其他的服务,因为服务注册中心本身的职责就是维护服务实例,它也不需要去检索其他服务

eureka.client.fetch-registry=false

#5.对外提供的注册入口

eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/

4.5 第三步:配置两个Eureka高可用(通讯)

--注意两个Eureka服务器,是通过主机名和端口来互相发现的。

       因此配置Eureka高可用,就是在配置主机名和端口。

主机名(eureka.instance.hostname)

服务端口(server.port)

Eureka 1

eureka1

5121

Eureka 2

eureka2

5122

4.5.1 修改第一个Eurekaapplication.properties文件

#1.配置端口

server.port=5121

#2.配置eureka主机名

eureka.instance.hostname=eureka1

#3.由于我们目前创建的应用是一个服务注册中心,而不是普通的应用,默认情况下,这个应用会向注册中心(也是它自己)注册它自己,设置为false表示禁止这种默认行为

eureka.client.register-with-eureka=false

#4.表示不去检索其他的服务,因为服务注册中心本身的职责就是维护服务实例,它也不需要去检索其他服务

eureka.client.fetch-registry=false

#5.对外提供的注册入口,关联其它的Eureka2

eureka.client.service-url.defaultZone=http://eureka2:5122/eureka/

4.5.2 修改第二个Eurekaapplication.properties文件

#1.配置端口

server.port=5122

#2.配置eureka主机名

eureka.instance.hostname=eureka2

#3.由于我们目前创建的应用是一个服务注册中心,而不是普通的应用,默认情况下,这个应用会向注册中心(也是它自己)注册它自己,设置为false表示禁止这种默认行为

eureka.client.register-with-eureka=false

#4.表示不去检索其他的服务,因为服务注册中心本身的职责就是维护服务实例,它也不需要去检索其他服务

eureka.client.fetch-registry=false

#5.对外提供的注册入口,关联其它的Eureka2

eureka.client.service-url.defaultZone=http://eureka1:5121/eureka/

4.5.3 修改本地hosts文件注册Eureka主机名

文件位置:C:\Windows\System32\drivers\etc\hosts。(注意:使用管理员身份编辑)

 

4.6 第四步:分别启动两个Eureka测试

--启动Eureka1成功

 

--启动Eureka2成功

 

--访问Eureka1控制台

 

--访问Eureka2控制台

 

4.7 第五步:测试Eureka高可用

步骤说明:

1)修改前面的实例,使用Eureka集群配置。

2)依次启动前面的实例。

3)通过instanceClient调用服务。

4)关闭其中一个Eureka,观察是否任然可以调用成功。

5)如果任然可用,则Eureka高可用配置成功。

4.7.1 修改实例instanceServerapplication.properties文件

#指定实例名

spring.application.name=instanceServer

#指定Eureka服务端访问路径,多个Eureka使用逗号隔开

eureka.client.service-url.defaultZone=http://eureka1:5121/eurekahttp://eureka2:5122/eureka

#指定实例端口

server.port=8080

4.7.2 修改实例instanceClientapplication.properties文件

#指定实例名

spring.application.name=instanceClient

#指定Eureka服务端访问路径,多个Eureka使用逗号隔开

eureka.client.service-url.defaultZone=http://eureka1:5121/eurekahttp://eureka2:5122/eureka

#指定实例端口

server.port=8081

4.7.3 修改实例instanceServer2application.properties文件

#指定实例名

spring.application.name=instanceServer

#指定Eureka服务端访问路径,多个Eureka使用逗号隔开

eureka.client.service-url.defaultZone=http://eureka1:5121/eurekahttp://eureka2:5122/eureka

#指定实例端口

server.port=8082

4.7.4 依次启动这三个实例

--启动实例instanceServer成功

 

--启动实例instanceClient成功

 

--启动实例instanceServer2成功

 

4.7.5 测试实例2调用远程服务

 

 

--测试成功。

4.7.6 测试Eureka高可用

--关闭Eureka1

 

--重新访问实例2

 

--测试成功。高可用配置成功!!!

Eureka安全认证

说明访问Eureka时,需要指定用户名、密码进行身份认证。

配置步骤说明:(1)在Eureka服务端,开启安全认证

             2)在Eureka客户端,进行身份认证

5.1 第一部分:在Eureka服务端开启身份认证

5.1.1 第一步添加身份认证依赖

--修改pom.xml文件

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-security</artifactId>

</dependency>

5.1.2 第二步:开启身份认证

--Eureka服务端,修改application.properties文件,指定用户名、密码

#配置Eureka安全认证

security.basic.enabled=true

security.user.name=root

security.user.password=gzsxt

说明如果配置了Eureka高可用Eureka之间相互访问时,需认证身份。

#1.配置端口

server.port=5121

#2.配置eureka主机名

eureka.instance.hostname=eureka1

#3.是否将自身注册为服务 false表示不注册

eureka.client.register-with-eureka=false

#4.是否主动发现服务  false表示不发现

eureka.client.fetch-registry=false

#5.对外提供的注册入口

eureka.client.service-url.defaultZone=http://root:gzsxt@eureka2:5122/eureka/

#配置Eureka安全认证

security.basic.enabled=true

security.user.name=root

security.user.password=gzsxt

5.2 第二部分:在Eureka客户端进行身份认证

--在服务系统中修改application.properties文件,进行身份认证

#指定Eureka服务端访问路径

eureka.client.service-url.defaultZone=http://root:gzsxt@eureka1:5121/eureka,http://root:gzsxt@eureka2:5122/eureka

SpringBoot项目打包发布

说明:(1SpringBoot项目推荐使用jar包的方式,来发布项目。

     2)如果是使用war方式创建的项目,则发布直接将war拷贝到tomcat 中。

步骤说明:(1)使用maven命令,将项目打成jar

         2)上传jarLinux服务器上

         3)编写启动文件,启动项目

6.1 第一步:使用Maven打包

说明使用maven clean  以及install命令来打包。

项目最终打包在target目录下

 

6.2 第二步上传到Linux环境

说明使用xftp文件传输工具jar上传到linux

 

6.3 第三步编写启动文件

1)创建start.sh文件    vim start.sh

#!/bin/bash

java -jar eurekaServer-1.0.jar

2)修改启动文件的权限,添加一个可执行权限

[root@node0927 eureka]# chmod 744 start.sh

3)执行该文件,启动jar包程序

说明:使用nohup ./start.sh &  来启动项目。

好处:后台启动

nohup说明:Linux中,将当前的线程转为后台执行的命令

[root@node0823 eureka]# nohup ./start.sh &

特别说明:当项目分布在多台机器上时,如果项目之间是通过主机名来发现的,那么要修改每一个机器的/etc/hosts文件,配置ip地址和主机名的关系。

192.168.4.253 eureka1

192.168.4.253 eureka2

1)其中 192.168.4.253是主机的ip地址,eureka是其对应的主机名

2)同一台机器的主机名可以配置多个。只要能对应上ip地址就行。

改造电商系统为springcloud分布式架构

思路:(1)在ego-project添加springcloud支持,锁定版本。

     2)改造ego-orderego-rest等注册服务实例系统。(即提供服务)

     3)改造ego-portal,使用springcloud发现服务,并且调用服务。

7.1 第一步改造ego-projectspringcloud系统

--说明修改pom.xml文件添加springcloud支持锁定版本

<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>cn.gzsxt.ego</groupId>

  <artifactId>ego-project</artifactId>

  <version>1.0</version>

  <packaging>pom</packaging>

  

  <parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>1.5.17.RELEASE</version>

<relativePath/> <!-- lookup parent from repository -->

  </parent>

  

  

  

  <!-- 集中定义依赖版本号 -->

<properties>

<junit.version>4.12</junit.version>

<spring.version>4.3.16.RELEASE</spring.version>

<mybatis.plus.version>2.3</mybatis.plus.version>

<mysql.version>5.1.40</mysql.version>

<slf4j.version>1.6.4</slf4j.version>

<jackson.version>2.9.5</jackson.version>

<druid.version>1.0.9</druid.version>

<httpclient.version>4.3.5</httpclient.version>

<jstl.version>1.2</jstl.version>

<servlet-api.version>2.5</servlet-api.version>

<jsp-api.version>2.0</jsp-api.version>

<joda-time.version>2.5</joda-time.version>

<commons-lang3.version>3.3.2</commons-lang3.version>

<commons-io.version>1.3.2</commons-io.version>

<commons-net.version>3.3</commons-net.version>

<commons-fileupload.version>1.3.1</commons-fileupload.version>

<jedis.version>2.7.2</jedis.version>

<solrj.version>4.10.3</solrj.version>

<activemq.version>5.9.0</activemq.version>

<java.version>1.8</java.version>

<spring-cloud.version>Edgware.SR5</spring-cloud.version>

</properties>

<dependencyManagement>

<dependencies>

<!-- 时间操作组件 -->

<dependency>

<groupId>joda-time</groupId>

<artifactId>joda-time</artifactId>

<version>${joda-time.version}</version>

</dependency>

<!-- Apache工具组件 -->

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>commons-lang3</artifactId>

<version>${commons-lang3.version}</version>

</dependency>

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>commons-io</artifactId>

<version>${commons-io.version}</version>

</dependency>

<dependency>

<groupId>commons-net</groupId>

<artifactId>commons-net</artifactId>

<version>${commons-net.version}</version>

</dependency>

<dependency>

<groupId>org.apache.activemq</groupId>

<artifactId>activemq-all</artifactId>

<version>${activemq.version}</version>

</dependency>

<dependency>

    <groupId>org.apache.activemq</groupId>

    <artifactId>activemq-pool</artifactId>

    <version>${activemq.version}</version>

</dependency>

<!-- Jackson Json处理工具包 -->

<dependency>

<groupId>com.fasterxml.jackson.core</groupId>

<artifactId>jackson-databind</artifactId>

<version>${jackson.version}</version>

</dependency>

<!-- httpclient -->

<dependency>

<groupId>org.apache.httpcomponents</groupId>

<artifactId>httpclient</artifactId>

<version>${httpclient.version}</version>

</dependency>

<!-- 单元测试 -->

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>${junit.version}</version>

<scope>test</scope>

</dependency>

<!-- 日志处理 -->

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>slf4j-log4j12</artifactId>

<version>${slf4j.version}</version>

</dependency>

<!-- Mybatis -->

<dependency>

<groupId>com.baomidou</groupId>

        <artifactId>mybatis-plus</artifactId>

        <version>${mybatis.plus.version}</version> 

</dependency>

<!-- MySql -->

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<version>${mysql.version}</version>

</dependency>

<!-- 连接池 -->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>druid</artifactId>

<version>${druid.version}</version>

</dependency>

<!-- Spring -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context</artifactId>

<version>${spring.version}</version>

</dependency>

<!-- Spring-JMS插件相关jar包依赖 -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-jms</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-beans</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-webmvc</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-jdbc</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-aspects</artifactId>

<version>${spring.version}</version>

</dependency>

<!-- JSP相关 -->

<dependency>

<groupId>jstl</groupId>

<artifactId>jstl</artifactId>

<version>${jstl.version}</version>

</dependency>

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>servlet-api</artifactId>

<version>${servlet-api.version}</version>

<scope>provided</scope>

</dependency>

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>jsp-api</artifactId>

<version>${jsp-api.version}</version>

<scope>provided</scope>

</dependency>

<!-- 文件上传组件 -->

<dependency>

<groupId>commons-fileupload</groupId>

<artifactId>commons-fileupload</artifactId>

<version>${commons-fileupload.version}</version>

</dependency>

<!-- Redis客户端 -->

<dependency>

<groupId>redis.clients</groupId>

<artifactId>jedis</artifactId>

<version>${jedis.version}</version>

</dependency>

<!-- solr客户端 -->

<dependency>

<groupId>org.apache.solr</groupId>

<artifactId>solr-solrj</artifactId>

<version>${solrj.version}</version>

</dependency>

<!-- 锁定springcloud版本 -->

<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>

  

<modules>

<!-- <module>ego-base</module> -->

<module>ego-manager</module>

<module>ego-rest</module>

<module>ego-portal</module>

<module>ego-search</module>

<module>ego-sso</module>

<module>ego-order</module>

</modules>

</project>

7.2 第二步:改造ego-order系统为注册服务实例系统

1)添加eureka客户端依赖支持,修改pom.xml文件

<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>cn.gzsxt.ego</groupId>

    <artifactId>ego-project</artifactId>

    <version>1.0</version>

  </parent>

  <artifactId>ego-order</artifactId>

  <packaging>war</packaging>

  

  <dependencies>

   <!-- 添加ego-base公共系统依赖 -->

   <dependency>

   <groupId>cn.gzsxt.ego</groupId>

    <artifactId>ego-base</artifactId>

    <version>1.0</version>

   </dependency>

  

   <dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

  

   <dependency>

            <groupId>com.baomidou</groupId>

            <artifactId>mybatisplus-spring-boot-starter</artifactId>

            <version>1.0.4</version>

        </dependency>

        

        <!-- 添加eureka客户端依赖 -->

        <dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>

</dependency>

  

   <!-- 导入spring-jdbc+事物 -->

   <dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-jdbc</artifactId>

</dependency>

  

   <!-- 导入切面依赖包 -->

   <dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-aspects</artifactId>

</dependency>

  

   <!-- 导入jdbc驱动+连接池 -->

   <!-- MySql -->

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

</dependency>

<!-- 连接池 -->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>druid</artifactId>

</dependency>

<dependency>

<groupId>com.fasterxml.jackson.core</groupId>

<artifactId>jackson-databind</artifactId>

</dependency>

  </dependencies>

  

</project>

2)修改application.properties文件,配置eureka服务器地址

#配置数据源

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/ego

spring.datasource.username=root

spring.datasource.password=gzsxt

#指定连接池的类型

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

#配置mybatis-plus

mybatis-plus.type-aliases-package=cn.gzsxt.base.pojo

#mybatis-plus.mapper-locations="clasapath:cn/gzsxt/base/mapper/*Mapper.xml"

mybatis-plus.global-config.db-column-underline=true

mybatis-plus.global-config.id-type=0

#配置server属性

server.port=8085

server.servlet-path=/order/*

#配置当前实例系统的名称

spring.application.name=EgoOrderInstance

#配置eureka注册中心的地址

eureka.client.service-url.defaultZone=http://root:gzsxt@eureka1:5121/eureka,http://root2:gzsxt2@eureka2:5122/eureka

3)修改启动类,添加eureka客户端注解依赖

package cn.gzsxt.order;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication

@EnableEurekaClient   //添加eureka客户端支持

public class EgoOrderApplication {

public static void main(String[] args) {

SpringApplication.run(EgoOrderApplication.class, args);

}

}

4)重启ego-order系统

 

5)在eureka管理控制台,查看服务注册情况

 

ego-order工程改造成功!!!

7.3 第三步:改造ego-portal工程为发现服务实例系统

1)添加eureka发现服务依赖,修改pom.xml文件

<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>cn.gzsxt.ego</groupId>

    <artifactId>ego-project</artifactId>

    <version>1.0</version>

  </parent>

  <artifactId>ego-portal</artifactId>

  <packaging>war</packaging>

  

  <dependencies>

   <!-- 添加ego-base公共系统依赖 -->

   <dependency>

   <groupId>cn.gzsxt.ego</groupId>

    <artifactId>ego-base</artifactId>

    <version>1.0</version>

   </dependency>

  

   <dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-feign</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-tomcat</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.tomcat.embed</groupId>

            <artifactId>tomcat-embed-jasper</artifactId>

        </dependency>

  

<!-- jsp视图依赖包 -->

<dependency>

<groupId>jstl</groupId>

<artifactId>jstl</artifactId>

</dependency>

<dependency>

<groupId>com.fasterxml.jackson.core</groupId>

<artifactId>jackson-databind</artifactId>

</dependency>

</dependencies>

  

</project>

2)修改application.properties文件,配置eureka注册中心地址

#配置视图解析器

spring.mvc.view.prefix=/WEB-INF/jsp/

spring.mvc.view.suffix=.jsp

#配置server属性

server.port=8082

server.servlet-path=*.html

#配置实例名称

spring.application.name=EgoPotalInstance

#配置eureka注册中心的地址

eureka.client.service-url.defaultZone=http://root:gzsxt@eureka1:5121/eureka,http://root2:gzsxt2@eureka2:5122/eureka

3)修改启动类,添加发现服务注解支持

package cn.gzsxt.portal;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.boot.builder.SpringApplicationBuilder;

import org.springframework.boot.web.support.SpringBootServletInitializer;

import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

import org.springframework.cloud.netflix.feign.EnableFeignClients;

@SpringBootApplication

@EnableDiscoveryClient

@EnableFeignClients

public class EgoPortalApplication extends SpringBootServletInitializer{

@Override

protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {

// TODO Auto-generated method stub

return builder.sources(EgoPortalApplication.class);

}

public static void main(String[] args) {

SpringApplication.run(EgoPortalApplication.class, args);

}

}

4)创建OrderServiceApi接口(interface),不需要实现。

package cn.gzsxt.portal.service;

import org.springframework.cloud.netflix.feign.FeignClient;

import org.springframework.web.bind.annotation.RequestMapping;

import cn.gzsxt.base.vo.EgoResult;

import cn.gzsxt.base.vo.OrderDetail;

@FeignClient(value="EgoOrderInstance")

public interface OrderServiceApi {

@RequestMapping("/order/create")

public EgoResult save(OrderDetail order);

}

5)修改OrderController类,使用springcloud远程调用保单订单接口

package cn.gzsxt.portal.controller;

import java.text.SimpleDateFormat;

import java.util.Calendar;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.ui.ModelMap;

import org.springframework.web.bind.annotation.RequestMapping;

import cn.gzsxt.base.vo.CartItem;

import cn.gzsxt.base.vo.EgoResult;

import cn.gzsxt.base.vo.OrderDetail;

import cn.gzsxt.portal.service.OrderService;

import cn.gzsxt.portal.service.OrderServiceApi;

@Controller

@RequestMapping("/order")

public class OrderController {

@Autowired

private OrderService orderService;

@Autowired

private OrderServiceApi orderServiceApi;

@RequestMapping("/order-cart")

public String showOrderCart(HttpServletRequest request){

List<CartItem> cart = orderService.getCart(request);

request.setAttribute("cartList", cart);

return "order-cart";

}

@RequestMapping("/create")

public String save(OrderDetail order,ModelMap map){

try {

EgoResult result = orderServiceApi.save(order);

if(200==result.getStatus()){

Long orderId = (Long) result.getData();

map.addAttribute("orderId", orderId);

map.addAttribute("payment", order.getPayment());

//预计送货时间,下单三天之后。

//默认送到时间,在3天后

Calendar c=Calendar.getInstance();

SimpleDateFormat df=new SimpleDateFormat("yyyy/MM/dd/E");

c.add(Calendar.DATE, 3);

System.out.println(df.format(c.getTime()));

map.addAttribute("date", df.format(c.getTime()));

return "success";

}

} catch (Exception e) {

e.printStackTrace();

}

map.addAttribute("message", "服务器忙,请稍后再试!");

return "error/exception";

}

}

6)重启ego-portal工程

 

7)访问eureka管理控制台

 

改造ego-portal订单模块成功!!!

猜你喜欢

转载自www.cnblogs.com/meizhoulqp/p/11299304.html