项目结构分析:
yml文件配置:
复制代码
1
2
3
4
5
6
7
8
9
10erver: port: 8090 spring: application: name: sca-consumer//子工程名 cloud: nacos: discovery: server-addr: localhost:8848 //nacos服务器
服务器消费方启动类:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66@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); } } }
服务器提供方启动类:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22@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; } } }
调用远端服务:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26package 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方式的远程调用异常处理:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21package 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文件依赖:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13<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依赖:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40<!--工程中默认定义的或自己定义的属性,例如一些版本信息--> <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-微服务基础架构内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复