概述
项目结构分析:
yml文件配置:
erver:
port: 8090
spring:
application:
name: sca-consumer//子工程名
cloud:
nacos:
discovery:
server-addr: localhost:8848 //nacos服务器
服务器消费方启动类:
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class,args);
}
/**创建RestTemplate对象,然后基于此对象进行远程服务调用*/
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
@Bean
@LoadBalanced //这个注解描述RestTemplate对象时,系统底层会对×××RestTemplate对象的请求进行拦截
public RestTemplate loadBalanceRestTemplate(){
return new RestTemplate();
}
@RestController
public class ConsumerController{
@Autowired
private RestTemplate restTemplate;
/**
* @Autowired注解描述属性时,会告诉spring框架,要优先按属性类型进行对象的查找和注入,假如
* 此类型的对象存在多个,此时还会按照属性名进行查找和比对,有相同的则直接注入(DI),没有相同
* 的则出错,当然也可以在属性上添加@Qualifier("bean的名字")注解,指定要注入的具体对象
*/
@Autowired
private RestTemplate loadBalanceRestTemplate;
//负载均衡客户端对象(基于此对象可以从nacos中获取服务列表,并且可以基于一定的算法
//从列表中获取一个服务实例)
@Autowired
private LoadBalancerClient loadBalancerClient;
@Value("${spring.application.name}")
private String appName;
//直接调用(非负载均衡方式)
//http://localhost:8090/consumer/doRestEcho1
@GetMapping("/consumer/doRestEcho1")
public String doRestEcho1(){
String url="http://localhost:8081/provider/echo/"+appName;
return restTemplate.getForObject(url,String.class);
}
//负载均衡方式的调用1
@GetMapping("/consumer/doRestEcho2")
public String doRestEcho2(){
//基于loadBalancerClient方式获取服务实例
String serviceId="sca-provider";//这个名字要在nacos的服务列表中
ServiceInstance choose = loadBalancerClient.choose(serviceId);
String ip=choose.getHost();
int port=choose.getPort();
//String url="http://"+ip+":"+port+"/provider/echo/"+appName;
String url=String.format("http://%s:%s/provider/echo/%s",ip,port,appName);
return restTemplate.getForObject(url,String.class);
}
//负载均衡应用方式2:@LoadBalance
@GetMapping("/consumer/doRestEcho3")
public String doRestEcho3(){
String serviceId="sca-provider";
String url=String.format("http://%s/provider/echo/%s",serviceId,appName);
return loadBalanceRestTemplate.getForObject(url,String.class);
}
}
}
服务器提供方启动类:
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class,args);
}
/**定义Controller对象(这个对象在spring mvc中给他的定义是handler),
* 基于此对象处理客户端的请求*/
@RestController
public class ProviderController{
//@Value默认读取项目配置文件中配置的内容
//8080为没有读到server.port的值时,给定的默认值
@Value("${server.port:8080}")
private String server;
//http://localhost:8081/provider/echo/tedu
@GetMapping("/provider/echo/{msg}")
public String doRestEcho1(@PathVariable String msg){
return server+" say hello "+msg;
}
}
}
调用远端服务:
package com.jt.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @FeignClient 注解用于描述远程服务调用接口,这个接口不需要你写实现类,你
* 只需要定义访问规则即可(例如请求方式,请求url,请求参数).
* @FeignClient注解描述的接口的实现类对象会默认交给spring管理,这个bean对象
* 的名字默认就是name属性指定的值,这个name还有一个层面的含义,就是你远程调用的
* 服务名.
* 说明:假如@FeignClient注解中添加了contextId属性,则这个属性值默认
* 会作为当前bean对象的名字,此时name的值仅仅作为要调用的服务名对待,一般
* 推荐contextId的值默认为@FeignClient注解描述的接口的名字(首字母小写)
*/
@FeignClient(name="sca-provider",
contextId = "remoteProviderService",
fallbackFactory = ProviderFallbackFactory.class)
public interface RemoteProviderService {
//@GetMapping表示以get请求方式调用远端服务
//"/provider/echo/{msg}"为远程调用服务的url
@GetMapping("/provider/echo/{msg}")
String echoMessage(@PathVariable("msg") String msg);
}
然而调用远端服务有时或发生异常状况,那么怎么处理异常呢??
Feign方式的远程调用异常处理:
package com.jt.feign;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
//此对象可以作为Feign方式的远程调用异常处理对象
@Component
public class ProviderFallbackFactory
implements FallbackFactory<RemoteProviderService> {
//当正常远程调用的服务不可用时,系统可以调用此方法进行请求处理
@Override
public RemoteProviderService create(Throwable throwable) {
return new RemoteProviderService() {//匿名内部类
@Override
public String echoMessage(String msg) {
//...通知运维人员(发短信,发邮件,电话)...
return "服务维护中";
}
};
}
}
项目结构:
子集工程pom文件依赖:
<dependencies>
<!--Web服务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--服务的注册和发现(我们要将服务注册到nacos)-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
父工程pom依赖:
<!--工程中默认定义的或自己定义的属性,例如一些版本信息-->
<properties>
<spring.boot.version>2.3.2.RELEASE</spring.boot.version>
<spring.cloud.version>Hoxton.SR9</spring.cloud.version>
<spring.cloud.alibaba.version>2.2.6.RELEASE</spring.cloud.alibaba.version>
</properties>
<!--dependencyManagement元素用于定义核心依赖的管理,例如依赖的版本-->
<dependencyManagement>
<dependencies>
<!--Spring boot 依赖(微服务基础)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<!--这里的import表示在其它工程中需要时直接可以引用-->
<scope>import</scope>
<!--假如依赖的scope属性值为import,则type类型必须为pom-->
<type>pom</type>
</dependency>
<!--Spring Cloud 依赖(定义了微服务规范)-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<!--Spring Cloud Alibaba依赖(基于spring微服务规范做了具体落地实现)-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
最后
以上就是无语烧鹅为你收集整理的java-微服务基础架构的全部内容,希望文章能够帮你解决java-微服务基础架构所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复