学习Spring Cloud与微服务之路四

    科技2022-09-05  111

    一、编译打包 1、在传统web项目在部署的时候,是编译出一个war包放到tomcat的webapps包下,而Spring Boot构建的web项目采用更加简单的内置容器方式来实现部署应用程序,只需要将应用编译成一个jar包,通过java-jar xx.jar命令就可用启动应用程序。

    mainClass配置的启动入口类,配置完成后可用通过maven的mvn clean package命令进行编译打包操作,编译完成后在target目录下会生成对应的jar包,部署的时候直接调用java-jar XX.jar即可启动应用。 二、Spring Boot Starter 1、通过引入各种Spring Boot Starter包可以快速搭建出一个项目的脚手架 2、目前的提供的Spring Boot Starter包,请看这篇文章 3、自动配置麻烦的是当出现错误时,排查问题的难度上升了,自动配置的逻辑都在Spring Boot Starter中,要想快速定位问题,就必须得了解Spring Boot Starter内部原理。 4、Spring Boot Starter项目创建 1)、创建一个项目,在pom.xml配置中新增maven依赖

    2)、创建一个配置类,用于在属性文件中配置值,相当于spring.data.mongo这种形式

    3)、再定义一个Client,相当于MongoTemplate,里面定一个方法,用于获取配置中的值 4)、自动创建客户端,自动配置类,构建UserClient实例 5)、客户端

    在属性文件中配置name的值和开启UserClient 访问/user/name就可以返回配置的值

    5、使用注解开启Starter自动构建 使用@Import({UserAutoConfigure.class}),通过导入的方式实现把UserAutoConfigure实例加入到SpringIOC容器中,这样就能开启自动配置

    6、使用配置开启Starter自动构建 使用@ConditionalOnProperty来指定是否开启配置的功能,只有当启动类加了@EnableUserClient并且配置文件中spring.user.enabled=true的时候才会自动配置UserClient

    7、配置starter内容提示,定义提示内容需要在META-INF中创建一个spring-configuration-metadata.json文件 name : 配置名 type : 配置的数据类型 defaultValue : 默认值 description : 配置内容的描述

    二、Eureka注册中心 1、注册中心在微服务框架中是必不可少的一部分,主要用来实现服务治理功能;Spring Cloud Eureka是Spring Cloud Netflix微服务套件的一部分,基于Netflix Eureka做了二次封装,主要负责实现微服务架构中服务治理功能。 2、Spring Cloud Eureka是一个基于REST的服务,并且提供了基于Java的客户端组件,能够非常方便地将服务注册到Spring Cloud Eureka中进行统一管理 3、使用Eureka编写注册中心服务 创建maven项目,在pom.xml中配置Eureka的依赖信息 创建启动类EurekaServerApplication,在@EnableEurekaServer注解,表示开启Eureka Server 然后再resources下面创建一个application.properties属性文件,增加下面的配置

    访问地址后,可以看到Eureka提供的web控制台

    4、创建项目注册到Eureka 首先创建一个maven项目,在pox.xml中增加相关依赖

    org.springframework.boot spring-boot-starter-parent 2.0.6.RELEASE org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-dependencies Finchley.SR2 pom import 然后在创建启动类,并在启动类上加上注解@EnableDiscoveryClient,表示当前服务是一个Eureka的客户端 package client.user;

    import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

    @EnableDiscoveryClient @SpringBootApplication public class App {

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

    }

    接下来在resources下面创建一个application.properties属性文件,配置如下配置

    spring.application.name=eureka-client-user-service server.port=8081 eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ #采用Ip注册 eureka.instance.prefer-ip-address=true #定义实例ID格式 eureka.instance.instance-id= s p r i n g . a p p l i c a t i o n . n a m e : {spring.application.name}: spring.application.name:{spring.cloud.client.ip-address}

    在启动服务,可以在控制台中输出注册信息的日志

    Registered instance EUREKA-CLIENT-USER-SERVICE/eureka-client-user-service:192.168.0.103 with status UP (replication=false)

    并且在Eureka的web控制台中可以看到新注册的服务信息 创建一个Controller,提供接口给其他服务查询

    package client.user.action;

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

    @RestController public class UserController{

    @GetMapping("/user/hello") public String hello() { return "hello world"; }

    }

    重启服务,访问http://localhost:8081/user/hello,调用成功则会返回字符串hello world

    5、直接调用接口 创建服务消费者,创建的pom.xml已经启动类都和上面的一样,唯一不同的地方是在application.properties 文件中的配置信息 spring.application.name=eureka-client-article-service server.port=8082

    同时需要增加RestTemplate配置,RestTemplate是Spring提供用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程http服务的方法,能够大大提供客户端的编写效率 package client.article.config;

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

    @Configuration public class BeanConfiguration {

    @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); }

    }

    创建接口,用于调用user/hello接口,使用RestTemplate调用接口

    package client.article.action;

    import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate;

    @RestController public class ArticleAction {

    @Autowired private RestTemplate restTemplate; @GetMapping("/article/callHello") public String callHello() { return restTemplate.getForObject("http://localhost:8081/user/hello",String.class); }

    }

    执行启动消费者服务,访问http://localhost:8082/article/callHello,访问成功后返回字符串,证明调用成功

    6、通过Eureka来消费接口 需要在RestTemplate的配置,添加一个@LoadBalanced注解,这个注解会自动构造LoadBalancerClient接口的实现类并注册到spring容器中 package client.article.config;

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

    @Configuration public class BeanConfiguration {

    @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); }

    }

    在接口调用代码上,只需要写成服务的名称,这个名称是属性文件中spring.application.name

    package client.article.action;

    import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate;

    @RestController public class ArticleAction {

    @Autowired private RestTemplate restTemplate; @GetMapping("/article/callHello2") public String callHello2() { return restTemplate.getForObject("http://eureka-client-user-service/user/hello",String.class); }

    } 访问http://localhost:8082/article/callHello2,可以正常返回字符串。

    7、开启Eureka认证 Eureka自带了一个web的管理页面,针对Eureka进行改造,加上权限认证来保证安全性 在pom.xml中添加spring-security的依赖包

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

    然后在application.properties中加上认证的配置信息

    #用于认证的用户名 spring.security.user.name=admin #用于认证的密码 spring.security.user.password=123456

    增加Security配置类

    package server.config;

    import org.springframework.context.annotation.Configuration; 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;

    @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter{

    @Override protected void configure(HttpSecurity http) throws Exception { //关闭csrf http.csrf().disable(); //支持httpBasic http.authorizeRequests().anyRequest().authenticated().and().httpBasic(); }

    }

    在重新启动注册中心,访问http://localhost:8761/,需要输入设置的用户和密码,输入正确后才能继续访问Eureka提供的管理页面

    在Eureka开启认证后,客户端注册的配置也要加上认证的用户名和密码信息 eureka.client.serviceUrl.defaultZone=http://admin:123456@localhost:8761/eureka/

    8、Eureka高可用搭建 在生产环境中必须搭建一个集群来保证高可用,Eureka的集群搭建方法很简单,每一个Eureka只需要在配置中指定另外多个Eureka的地址就可以实现一个集群的搭建了。

    9、关闭自我保护 保护模式主要在一组客户端和Eureka Server之间存在网络分区场景时使用,一旦进入保护模式,Eureka Server将会尝试保护其服务的注册表中的信息,不删除服务注册表中的数据,当网络故障恢复后,该Eureka Server节点会自动退出保护模式

    也可以通过下面的配置将自我保护模式关闭,这个配置是在eureka-server中

    #关闭自我保护 eureka.server.enable-self-preservation=false

    自定义Eureka的InstanceID,客户端注册时,服务的Instance ID的默认值的格式如下

    s p r i n g . c l o u d . c l i e n t . h o s t n a m e : {spring.cloud.client.hostname}: spring.cloud.client.hostname:{spring.application.name}:KaTeX parse error: Expected '}', got 'EOF' at end of input: …on.instance_id:{server.port}} 翻译过来就是主机名:服务名称:服务端口,可以自定义成

    s p r i n g . a p p l i c a t i o n . n a m e : {spring.application.name}: spring.application.name:{spring.cloud.client.ip-address}😒{server.port}

    在Eureka的web管理页面上可以看到注册之后的信息

    快速移除已经失效的服务信息,可以通过在eureka-server中增加两个配置,分别是关闭自我保护和清理间隔 然后在具体的客户端服务中配置下面的内容,eureka.client.healthcheck.enabled用于开启健康检查,需要在pom.xml引入actuator的依赖

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
    Processed: 0.008, SQL: 9