随笔 - 134,  文章 - 0,  评论 - 0,  阅读 - 21282

六Spring Cloud

回顾之前的:

  • javaSE
  • 数据库
  • 前端
  • Servlet
  • HTTP
  • Mybatis
  • Spring
  • SpringMVC
  • SpringBoot
  • Dubbo、Zookeeper、分布式基础
  • Maven、Git
  • Ajax、json

微服务产生的背景

单体架构

单体业务的问题:

  • 随着业务的发展,开发变得越来越复杂
  • 修改、新增某个功能,需要对整个系统进行车市,从新部署
  • 一个模块出现问题,横坑能导致整个系统的崩溃
  • 对团队同事对数据进行管理,容易产生安全漏洞
  • 各个模块视同同一种的技术框架,局限性太大,很难根据业务选择最适合的技术架构
  • 模块的内容太复杂,如果员工离职,可能要横长时间才能完成任务的交接

为了解决上述问题微服务架构营运而生,简单来说,微服务就是将一个单体应用拆分成

若干个小型的服务,协同完成系统功能的一种架构模式,在系统架构层面进行解耦合,讲一个复杂的问题拆分成若干个简单的问题。

这样的好处对于每一个简单的问题,开发维护部署的难度降低很多,就可以实现自治,可以自主选择最适合的技术框架,提高了项目的灵活性

微服务框架不仅仅是简单的拆分,拆分之后的各个服务之间还要进行通信,否则就无法协同完成需求

微服务之间只需要制定统一的协议即可,至于每个微服务之间使用什么样的技术框架来完成,统统不要关心

这种松耦合的方式开发,部署都变得灵活同事系统更容易扩展,减低了开发、运维的难度。

程序员的境界

1.使用框架

2.掌握技术 自己写框架

3.解决问题

分布式服务

微服务的优点

  • 各个服务之间实现了松耦合,彼此之间不再关注对方是使用什么语言开发,什么技术,只需要保证自己的接口的正常访问,通过标准协议访问其他的接口即可
  • 各个微服务之间独立自治,只需要专注的做好自己的业务即可
  • 微服务是一种去中性化的架构方式,相当于用零件的方式凭借一台机器,如果米格零件出现问题,可以随时替换从而保证机器的正常运行

微服务的不足

  • 各个服务之间是利用系统调用使用的,如果某个微服务的远程调用出现问题,导致微服务不可用,就可能产生级联反应,造成整个系统的崩溃
  • 如果某个需求要调用多个微服务,如何来保证数据的一致性
  • 相比较于单体应用微服务学习难度会增加,对于团队新加入的员工来讲如何快速上手微服务是个问题

微服务的设计原则

从大到小、提炼出核心需求、搞清楚服务间的交互关系,先拆分粒度较大的服务,然后再根据具体的业务需求逐步细化服务粒度,最终形成一套合理的微服务系统架构

  • 微服务的粒度不能太呆也不能太小,避免出现多个微服务处理同一个需求 单一职责
  • 各个微服务之间要相互独立,自治,自主开发、自主测试、自主部署、自主维护 面向服务
  • 保证数据的独立性、各个微服务独立管理业务模型下的数据 自治
  • 使用RESTful协议完成微服务之间的任务协助,数据交互采用JSON的格式,方便整和调用 隔离性强

微服务架构的核心组件

  • 服务治理
    • 服务注册
    • 服务发现

提供服务的叫服务提供者,调用服务的叫服务消费者。

  • 服务负载均衡(高并发)
  • 服务网关
  • 微服务的容错机制
  • 分布式配置
  • 服务监控

解决方案

最好的就是:

spring cloud 和 阿里巴巴的Dubbo

功能 Dubbo Spring Cloud SpringCloudAlibaba
注册中心 zookeer、Redis Eureka、Consul Nacos、Eureka
服务远程调用 Dubbo协议 Feign(http协议) Dubbo、Feign
配置中心 SpringCloudConfig SpringCloudConfig、Nacos
服务网关 SpringCloudGateway、Zuul SpringCloudGateway、Zuul
服务监控 dubbo-admin\功能弱 Hystrix Sentinel
  • springCloud+Feign---Restful
  • SpringCloud+Feign----Restful
  • SpringCloudAlibaba+Dubbo----Dubbo方式
  • Dubbo原始模式 (2012年) ----Dubbo

Spring Cloud

微服务时分布式软件架构的设计方式,具体的落地方案有衡多,Dubbo \Spring Boot/Srong Cloud\ Motan等等,spring cloud 基于spring boot 使得整体的开发、部署、配置都非常的简单、可以快速搭建基于微服务的分布式应用,springcloud相当于微服务的各个组件的集大成者

Spring boot 和Spring cloud的关系

Spring boot快速搭建基础的系统,Spring Cloud在此基础上实现了分布式微服务系统中的公共组件,入服务注册、服务发现、配置管理、熔断器、总线控制、服务调度方式是基于REST API。

  • 服务治理 Eureka
  • 服务通信 Ribbon
  • 服务通信 Feign
  • 服务容错 Hystrix
  • 服务配置 Config
  • 服务监控 Actuator
  • 服务跟踪 Zipkin

搭建微服务系统的核心中枢

服务治理的核心组件

  • 服务提供者
  • 服务消费者
  • 注册中心

分布式系统架构中,每个微服务再批董事,将自己的信息存储在注册中心,服务注册

服务消费者从注册中心查询的服务提供者的网络信息,并且通过词信息调用服务提供者的接口,服务发现。

注册中心管理各个微服务:通过心跳机制,每隔一段时间微服务回想注册中兴进行汇报,如果注册中心长时间无法与某个微服务通信,就自动销毁该服务

当某个服务的网络信息发声改变时,会重新注册。

服务者、服务消费者、注册中心的关联:

  • 启动注册中心
  • 服务提供者启动,在注册中心注册一个可以提供服务的实例
  • 服务消费者启动,在注册中心订阅需要调用的服务
  • 在注册中心将服务提供者的信息推送该服务调用者
  • 服务调用者调用相关信息(IP.端口)调用服务提供者的服务

注册中心的核心模块

  • 服务注册表
  • 服务注册
  • 服务发现
  • 服务检查

spring cloud的服务治理用Eureka组件

什么是Eureka组件

spring cloud Eureka ,提供服务注册和服务发现的功能。

一:spring cloud Eureka

Eureka Server 服务端

Eureka Client 客户端

服务注册

代码实现:

1.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.example</groupId>
    <artifactId>springCloud01</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>EurekaServer</module>
    </modules>
    <!--    父工程-->
    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.0.7.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--        JDk9-->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

2.父工程下实现一个子模块Module实现Eureka Server

<?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">
    <parent>
        <artifactId>springCloud01</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>EurekaServer</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

</project>

3.配置文件

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

4.创建启动类:

package com.southwind;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

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

5.检查打开

http://localhost:8761

注册第一个微服务

服务提供者

服务消费者和服务提供者都是通过Eureka Client 连接到Eureka Server完成注册。

1.创建一个模块,实现Eureka Client

<?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">
    <parent>
        <artifactId>springCloud01</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>provider</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

</project>

2.配置文件:

server:
  port: 8010
spring:
  application:
    name: provider
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

3.创建启动类:

package com.southwind;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

4.数据持久化:

接口:

package com.southwind.repository;

import com.southwind.entity.Student;

import java.util.Collection;

public interface StudentRepository {
    public Collection<Student> findAll();
    public Student findById(Integer id);
    public  void saveOrUpdate(Student student);
    public void deleteById(Integer id);
}

实现类:

package com.southwind.repository.impl;

import com.southwind.entity.Student;
import com.southwind.repository.StudentRepository;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class StudentRepositoryImpl implements StudentRepository {
    private static Map<Integer,Student> map;
    static {
        map=new HashMap<>();
        map.put(1,new Student(1,"张三"));
        map.put(1,new Student(2,"李四"));
        map.put(1,new Student(3,"王五"));
    }
    @Override
    public Collection<Student> findAll() {
        return map.values();
    }

    @Override
    public Student findById(Integer id) {
        return map.get(id);
    }

    @Override
    public void saveOrUpdate(Student student) {
        map.put(student.getId(),student);
    }

    @Override
    public void deleteById(Integer id) {
        map.remove(id);
    }
}

Handler:

package com.southwind.Handler;

import com.southwind.entity.Student;
import com.southwind.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;

@RestController
@RequestMapping("/provider")
public class StudentHandler {
    @Autowired
    private StudentRepository studentRepository;
    @GetMapping("/findall")
    public Collection<Student> findall(){
        return studentRepository.findAll();
    }
    @GetMapping("/findbyid/{id}")
    public Student findById(@PathVariable("id") Integer id){
        return studentRepository.findById(id);
    }
    @PostMapping("/save")
    public void save(@RequestBody Student student){
        studentRepository.saveOrUpdate(student);
    }
    @DeleteMapping("/delete")
    public void deletebyid(Integer id){
        studentRepository.deleteById(id);
    }

}

二:RestTemplate

通过RestTemplate可以实现不同微服务之间的调用

RestTemplate是spring框架提供的一种基于RESTful的服务组件,底层对HTTP请求及其相应进行了封装,提供了很多的远程访问REST服务的方式,可以简化代码的开发

如何使用RestTemplate

1.创建maven工程

<?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.example</groupId>
    <artifactId>springCloud02</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.0.7.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<!--        lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>

2.创建实体类:

package com.southwind.entity;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class User {
    private Integer id;
    private String name;
}

3.持久层

接口:

package com.southwind.repository;

import com.southwind.entity.User;

import java.util.Collection;

public interface UserRepository {
    public Collection<User> findAll();
    public User findById(Integer id);
    public void saveOrUpdate(User user);
    public void deleteById(Integer id);
}

实体类:

package com.southwind.repository.impl;

import com.southwind.entity.User;
import com.southwind.repository.UserRepository;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class UserRepositoryImpl implements UserRepository {
    private static Map<Integer,User> map;
    static {
        map=new HashMap<>();
        map.put(1,new User(1,"张三"));
        map.put(2,new User(2,"李四"));
        map.put(3,new User(3,"王五"));

    }
    @Override
    public Collection<User> findAll() {
        return map.values();
    }

    @Override
    public User findById(Integer id) {
        return map.get(id);
    }

    @Override
    public void saveOrUpdate(User user) {
        map.put(user.getId(),user);
    }

    @Override
    public void deleteById(Integer id) {
        map.remove(id);
    }
}

测试接口可以使用

RestTemplate访问服务REST服务

1.将RestTemplate的实例化对象通过@Bean注解注入到IoC容器

package com.southwind.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class MyConfig {
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
  • 方法名为id名

2.创建RestHandler

package com.southwind.Handler;

import com.southwind.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.Collection;

@RestController
@RequestMapping("/rest")
public class RestHandler {
    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("/findall")
    public Collection<User> findAll(){
        return restTemplate.getForObject("http://localhost:8080/user/findall",Collection.class);
    }
    @GetMapping("/findbyid/{id}")
    public User findById(@PathVariable("id") Integer id){
        return restTemplate.getForObject("http://localhost:8080/user/findbyid/{id}",User.class,id);
    }
    @PostMapping("/save")
    public void save(@RequestBody User user){
         restTemplate.postForObject("http://localhost:8080/user/save",user,Collection.class);
    }
    @PutMapping("/update")
    public void update(User user){
        restTemplate.put("http://localhost:8080/user/save",user);
    }
    @DeleteMapping("/delete{id}")
    public void delete(@PathVariable("id") Integer id){
        restTemplate.delete("http://localhost:8080/user/delete{id}",id);
    }
}

**底层RestTemplate是对http请求和相应的封装,提供了很多访问远程REST服务的方法,基于它的这个特性,我们可以实现不同微服务之间的调用。

服务消费者

1.创建Module,配置环境

<?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">
    <parent>
        <artifactId>springCloud01</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>consumer</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
</project>

2.application.yml

server:
  port: 8020
spring:
  application:
    name: consumer
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

3.启动类:

package com.southwind;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

4.Handler

package com.southwind.controller;

import com.southwind.entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.Collection;

@RestController
@RequestMapping("/consumer")
public class StudentHandler {
    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("/findall")
    public Collection<Student> findall(){
        return restTemplate.getForObject("http://localhost:8010/provider/findall",Collection.class);
    }
    @GetMapping("/findbyid/{id}")
    public Student findById(@PathVariable("id") Integer id){
        return restTemplate.getForObject("http://localhost:8010/provider/findbyid/{id}",Student.class,id);
    }
    @PostMapping("/save")
    public void save(@RequestBody Student student){
        restTemplate.postForObject("http://localhost:8010/provider/save",student,Collection.class);
    }
    @DeleteMapping("/delete")
    public void deletebyid(Integer id){
        restTemplate.delete("http://localhost:8010/provider/delete/{id}",id);
    }
}

5.配置类:

package com.southwind.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class MyConfig {
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

服务网关

API网关可以对所有的API请求进行统一的管理和维护,相当于为系统开放出一个统一的接口,所有的外部的请求只需要统一的访问这个外部接口即可,系统内部再通过API网关映射不同的微服务。

对于开发者就不需要关注具体的微服务URL,直接访问网关即可

三:Spring Cloud Zuul

1.创建模块,配置环境

<?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">
    <parent>
        <artifactId>springCloud01</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>gateway</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
</project>

2.application.yml

server:
  port: 8030
spring:
  application:
    name: gateway
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
zuul:
  routes:
    provider: /p/**

3.启动类:

package com.southwind;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@EnableZuulProxy
@EnableAutoConfiguration
public class GetwayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GetwayApplication.class,args);
    }

}

网关不仅可以路由映射,还自带了负载均衡

四:Ribbon 负载均衡

分布式高并发

Spring Cloud 提供的一种负载均衡的解决方案,Ribbon 是Netfix发布的负载均衡器,springcloud Ribbon 的使用同样要结合Eureka Server

负载均衡算法:轮询、随机、加权轮询、加权随机

1.创建模块,配置环境

<?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">
    <parent>
        <artifactId>springCloud01</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>ribbon</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
</project>

2.application.yml

server:
  port: 8040
spring:
  application:
    name: ribbon
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

3.创建启动类:

package com.southwind;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

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

4.实体类:

package com.southwind.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private Integer id;
    private String name;

}

5.controller

package com.southwind.controller;

import com.southwind.entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Collection;

@RestController
@RequestMapping("/ribbon")
public class RibbonHandler {
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/findall")
    public Collection<Student> findall(){
        return restTemplate.getForObject("http://provider/provider/findall",Collection.class);
    }
    @GetMapping("/index")
    public String index(){
        return restTemplate.getForObject("http://consumer/consumer/index",String.class);
    }
}

网关加不了逻辑,只是简单的路由的映射

五:Fiegn 声明式接口调用

什么是Fiegn

Netfix,Fiegn 是一个提供模板式的Web Service客户端,使用Fiegn 可以简化Web Service 客户端的编写,开发者可以通过简单的接口和注解来调用HTTP API

Spring Cloud Fiegn :可插拔、基于注解、负载均衡、服务器熔断

只需要创建接口,同时在接口上添加关注注解即可

Fiegn 和Ribbion的区别:

  • Ribbion是一个HTTP客户端工具,Fiegn 是基于Ribbion,更加灵动
  • 支持Fiegn 注解,spring mvc 注解
  • Fiegn 基于Ribbion实现
  • Fiegn 集成了Hystrix

1.创建模块,配置环境

<?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">
    <parent>
        <artifactId>springCloud01</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>feign</artifactId>

    <dependencies>
        <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-openfeign</artifactId>
        </dependency>
    </dependencies>
</project>

2.配置文件

server:
  port: 8050
spring:
  application:
    name: fegin
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

3.启动类

package com.southwind;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

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

4.Handler

package com.southwind.Handler;

import com.southwind.entity.Student;
import com.southwind.fegin.FeignProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;

@RestController
@RequestMapping("/feign")
public class FeignHandler {
    @Autowired
    private FeignProviderClient feignProviderClient;

    @GetMapping("/findall")
    public Collection<Student> findall(){
        return feignProviderClient.findall();
    }
    @GetMapping("/findbyid/{id}")
    public Student findbyid(@PathVariable("id") Integer id){
        return feignProviderClient.findbyid(id);
    }
    @PostMapping("/save")
    public void save(@RequestBody Student student){
        feignProviderClient.save(student);
    }
    @DeleteMapping("/delete")
    public void deletebyid(Integer id){
        feignProviderClient.delete(id);
    }
}

5.声明的接口:

package com.southwind.fegin;

import com.southwind.entity.Student;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;

@FeignClient(value = "provider")
public interface FeignProviderClient {
    @GetMapping("/provider/findall")
    public Collection<Student> findall();
    @GetMapping("/provider/findbyid/{id}")
    public Student findbyid(@PathVariable("id") Integer id);
    @PostMapping("/provider/save")
    public void save(@RequestBody Student student);
    @DeleteMapping("/provider/delete/{id}")
    public void delete(@PathVariable("id") Integer id);
}

六:Hystrix容错监控机制

什么是微服务的容错机制

提前预设解决方案、,系统自主调节,遇到问题即时处理

什么是Hystrix

Netfix

设计原则:

  • 服务隔离机制
  • 服务降级
  • 熔断机制
  • 提供实时的监控和报警功能
  • 提供实事的配置修改功能

1.创建一个模块,配置环境

<?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">
    <parent>
        <artifactId>springCloud01</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>hystrix</artifactId>

    <dependencies>
        <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-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
    </dependencies>
</project>

2.application.yml

server:
  port: 8060
spring:
  application:
    name: hystrix
eureka:
  client:
    service-url:
      default: http://localhost:8761/eureka
  instance:
    prefer-ip-address: true
feign:
  hystrix:
    enabled: true
management:
  endpoints:
    web:
      exposure:
        include: 'hystrix.stream'

3.创建启动类

package com.southwind;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.openfeign.EnableFeignClients;

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

4.实体类:

package com.southwind.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private Integer id;
    private String name;

}

5.接口:

package com.southwind.fegin;

import com.southwind.entity.Student;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;

@FeignClient(value = "provider")
public interface FeignProviderClient {
    @GetMapping("/provider/findall")
    public Collection<Student> findall();
    @GetMapping("/provider/findbyid/{id}")
    public Student findbyid(@PathVariable("id") Integer id);
    @PostMapping("/provider/save")
    public void save(@RequestBody Student student);
    @DeleteMapping("/provider/delete/{id}")
    public void delete(@PathVariable("id") Integer id);
}

6.controller

package com.southwind.Handler;

import com.southwind.entity.Student;
import com.southwind.fegin.FeignProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;

@RestController
@RequestMapping("/hystrix")
public class FeignHandler {
    @Autowired
    private FeignProviderClient feignProviderClient;

    @GetMapping("/findall")
    public Collection<Student> findall(){
        return feignProviderClient.findall();
    }
    @GetMapping("/findbyid/{id}")
    public Student findbyid(@PathVariable("id") Integer id){
        return feignProviderClient.findbyid(id);
    }
    @PostMapping("/save")
    public void save(@RequestBody Student student){
        feignProviderClient.save(student);
    }
    @DeleteMapping("/delete")
    public void deletebyid(Integer id){
        feignProviderClient.delete(id);
    }
}

数据监控的url

7.添加可是化页面组件

<!--        可视化依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>

8.启动类添加组件

@EnableHystrixDashboard

package com.southwind;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
@EnableHystrixDashboard
public class hystrixApplication {
    public static void main(String[] args) {
        SpringApplication.run(hystrixApplication.class,args);
    }
}

http://localhost:8060/hystrix 可视化界面url

七:Spring Cloud Config 本地配置

本地文件系统

我们可以将微服务的相关配置文件存储到本地文件中,然后让微服务来读取本地文件。

创建本地文件 Config Server

1.创建模块,配置环境

<?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">
    <parent>
        <artifactId>springCloud01</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>nativeConfigServer</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
    </dependencies>

</project>

2.配置application.yml

server:
  port: 8762
spring:
  application:
    name: nativeconfigserver
 profiles:
   active: native
  cloud:
    config:
      server:
        native:
          search-location: classpath:/shared

3.创建文件夹shared、文件configclient-dev.yml

server:
  port: 8070
foo: foo version 1

4.编写启动类

package com.southwind;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

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

配置中心已经完成

创建客户端

1.创建模块,配置环境

<?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">
    <parent>
        <artifactId>springCloud01</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>nativeconfigclient</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
    </dependencies>

</project>

2.创建文件

bootstrap.yml

spring:
  application:
    name: configclient
  profiles:
    active: dev
  cloud:
    config:
      uri: http://localhost:8762
      fail-fast: true

3启动类:

package com.southwind;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

4.handler:

package com.southwind.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/native")
public class NativeConfigHandler {
    @Value("${server.port}")
    private String port;
    @Value("${foo}")
    private String foo;
    @GetMapping("/index")
    public String index(){
        return this.port+"---"+this.foo;
    }
}

八:服务跟踪:

Zipkin 实现服务跟踪

什么是Zipkin ?

  • Zipkin Server 追踪
  • Zipkin Client 图形界面

Spring Cloud Sleuth 集成了Zipkin

Zipkin Server

1创建模块,配置环境

<?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">
    <parent>
        <artifactId>springCloud01</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>zipkin</artifactId>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
<!--    Zipkin -->
    <dependency>
        <groupId>io.zipkin.java</groupId>
        <artifactId>zipkin-server</artifactId>
        <version>2.9.4</version>
    </dependency>
    <dependency>
        <groupId>io.zipkin.java</groupId>
        <artifactId>zipkin-autoconfigure-ui</artifactId>
        <version>2.9.4</version>
    </dependency>
</dependencies>
</project>

2.application.yml

server:
  port: 9090

3.启动类

package com.southwind;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import zipkin.server.internal.EnableZipkinServer;

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

创建Zipkin Client

1.创建模块,导入依赖

<?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">
    <parent>
        <artifactId>springCloud01</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>zipkinClient</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
    </dependencies>
</project>

2.application.yml

server:
  port: 8090
spring:
  application:
    name: zipkinclient
  sleuth:
    web:
      client:
        enabled: true
    sampler:
      probability: 1.0
  zipkin:
    base-url: http://localhost:9090/
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

3.创建客户端的启动类:

package com.southwind;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

4.创建Handler

package com.southwind.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/zipkin")
public class zipkinHandler {
    @Value("${server.port}")
    private String port;
    @GetMapping("/index")
    public String index(){
        return this.port;
    }
}
posted on   Steam残酷  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
点击右上角即可分享
微信分享提示