- 微服务
概念:
软件即服务,程序中的微服务,就是将各个业务系统的共性再进行抽取,做成独立的服务。
项目结构:
GitCGB2105IVProjects (工作区/空项目)
01-sca //(微服务父工程)
sca-provider //服务提供方法
sca-consumer //服务消费方法
sca-gateway //网关服务 - Nacos服务注册以及负载均衡
- 主Module
pom.xml:
<modules>
<module>sca-provider</module>
<module>sca-consumer</module>
<module>sca-gateway</module>
</modules>
<!-- 1.定义子工程中核心依赖的版本管理(只是版本管理) -->
<dependencyManagement>
<dependencies>
<!-- spring boot核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring Cloud微服务规范 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring Cloud Alibaba基于spring Cloud规范 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 2.公共依赖-->
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<!-- 3.当前工程模块及子工程的统一编译和运行版本-->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
- nacos-provider
pom.xml:
<parent>
<artifactId>01-sca</artifactId>
<groupId>com.jt</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sca-provider</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
application.yml:
server:
port: 8082
spring:
application:
name: sca-provider
cloud:
discovery:
server-addr:localhost:8848
ProviderController:
package com.jt.privider.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/*
*创建一个服务提供方对象,通过此对象处理消费端请求
* */
@RestController
public class PrividerController {
@Value("${server.port}")
private String server;
/*请求处理对象通过方法处理客户端或者消费端请求,
*当前方法用于向客户端或者服务的消费端返回一个字符串消息*/
@GetMapping("/provider/out/{str}")
public String Out(@PathVariable String str){
return server+"say:hello,"+ str;
}
}
- Nacos-consumer
pom.xml:
<parent>
<artifactId>01-sca</artifactId>
<groupId>com.jt</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sca-consumer</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Feign中的API封装了远程服务调用方式以及错误机制-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
ComsumerApplication:
//用于告诉spring框架,要对使用@FeignClient注解描述的接口创建期实现类以及对象
@EnableFeignClients
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
//使用注解描述RestTemplate对象时,假如使用RestTemplate对象发起远程服务调用,底层会对这个请求进行拦截,拦截后,
//会基于LoadBalanceClient对象获取服务实例,然后进行负载均衡的调用
@Bean
@LoadBalanced
public RestTemplate loadBalancedRestTemplate(){
return new RestTemplate();
}
}
ConsumerController:
//定义服务消费端Controller,在这个对象中实现对远端服务sca-provider的调用
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;//Spring容器中的对象,通过此对象调用远端服务
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private RestTemplate loadBalancedRestTemplate;
@Value("${spring.application.name}")
private String server;
@GetMapping("consumer/Out2")
public String Out2(){
//1.定义远端要调用的URL
String url = "http://localhost:8081/provider/out/"+server;
//2.基于restTemplate对象的相关方法进行服务调用
return restTemplate.getForObject(url, String.class);
}
@GetMapping("consumer/Out3")
public String Out3(){
ServiceInstance serviceInstance = loadBalancerClient.choose("sca-provider");
String url = String.format("http://%s:%s/provider/out/%s",serviceInstance.getHost(),serviceInstance.getPort(),server);
System.out.println("request url:"+url);
return restTemplate.getForObject(url, String.class);
}
//简化:为RestTemplate对象注入拦截器,在底层拦截中实现服务实例的获取
@GetMapping("/consumer/Out4")
public String Out4(){
//sca-provider为nacos服务列表中的一个服务名
String url=String.format("http://%s/provider/echo/%s","sca-provider",server);
//向服务提供方发起http请求,获取响应数据
return loadBalancedRestTemplate.getForObject(
url,//要请求的服务的地址
String.class);//String.class为请求服务的响应结果类型
}
}
RemoteProviderService:
//用于定义远程调用规范,其中,name的值为远端服务名,同时也会将这个名字
//作为RemoteProviderService接口实现类的Bean对象名字
@FeignClient(name = "sca-provider")
public interface RemoteProviderService {
@GetMapping("/provider/out/{msg}")
String echoMsg(@PathVariable("msg") String msg);
}
FeignConsumerController:
@RestController
@RequestMapping("/consumer/")
public class FeignConsumerController {
@Autowired
private RemoteProviderService remoteProviderService;
/**基于feign方式的服务调用*/
@GetMapping("/out/{msg}")
public String doFeignEcho(@PathVariable("msg") String msg){
//基于feign方式进行远端服务调用(前提是服务必须存在)
return remoteProviderService.echoMsg(msg);
}
}