此章节将基于上一章节基础之上,引入Soul网关,至于Soul网关是干什么的,怎么做的,我们会在后续章节讲解,1-3章节侧重于搭建应用。
本章节的Soul网关接入,如果你1,2章节都是和我保持一致,那么只需要直接启动Soul网关即可,但是对应的provider,consumer应用是需要额外的代码接入的。
开发环境和第二章保持一致。
3.1 提供者接入Soul
3.1.1 pom
<dependency> <groupId>org.dromara</groupId> <artifactId>soul-spring-boot-starter-client-alibaba-dubbo</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>org.dromara</groupId> <artifactId>soul-spring-boot-starter-client-springmvc</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>org.dromara</groupId> <artifactId>soul-client-springmvc</artifactId> <version>2.2.0</version> </dependency>
3.1.2 Controller
与之前不同的是,这里我们会在Controller增加一个注解,@SoulSpringMvcClient,标注其注册成为一个SoulSpringMvcClient对象。这里有两种方式,一种是全局,一种是下面示例文件的局部,我会在 3.1.3 配置文件具体讲解二者实现上的差异性。
其中@SoulSpringMvcClient(path = "/consumer/** "), ** 标识允许访问:consumer路径下全部,如果在当前Controller中,你只想部分暴露,那么更正为:
- 删除Controller上的:SoulSpringMvcClient(path = "/consumer/** ")
- 在对应需要暴露的接口上,加上全路径,如: @SoulSpringMvcClien(path = "/consumer/getUserById")
package com.youzha.dubbo.Controller; import com.youzha.dubbo.dto.ResultDTO; import com.youzha.dubbo.entity.User; import com.youzha.dubbo.service.RemoteUserService; import lombok.extern.slf4j.Slf4j; import org.dromara.soul.client.springmvc.annotation.SoulSpringMvcClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; /** * @author youzhaxiaobo * @version 1.0 * @date 2020/7/1 19:30 * @Desc */ @Slf4j @RestController @RequestMapping("/consumer") @SoulSpringMvcClient(path = "/consumer/**") public class ConsumerController { @Autowired private RemoteUserService userService; @GetMapping(value = "/getUserById", produces = MediaType.APPLICATION_JSON_VALUE) public ResultDTO getUserById(@RequestParam("id") int id) { log.info("id=" + id); User user = userService.findById(id); log.info("消费者获取用户,信息为:{}", user); if(null == user) { return new ResultDTO(-1, "获取失败"); } return new ResultDTO(200, "获取成功", user); } @GetMapping(value = "/helloWorld", produces = MediaType.APPLICATION_JSON_VALUE) public ResultDTO helloWorld() { log.info("id=" + 1); User user = userService.findById(1); log.info("消费者获取用户,信息为:{}", user); if(null == user) { return new ResultDTO(-1, "获取失败"); } return new ResultDTO(200, "获取成功", user); } }
3.1.3 配置文件
soul: # 网关http配置 http: adminUrl: http://127.0.0.1:9093 contextPath: /consumer appName: consumer full: false port: 9092
说明:
- http:标注这里协议是Http,同样还有(dubbo等)
- adminUrl:对应soul-admin启动的应用地址,端口
- contextPath:对应注册进Soul的路由前缀(即我们后续通过网关访问的限制名,多个应用应不同)
- appName:对应的应用名称,不配置的话,会默认取 dubbo配置中application 中的名称
- full:true则表示代理全部,全局允许访问,权限很大;false表示非全局,只访问有注解的地方(推荐)
- port:当前应用的启动端口,并非soul-admin或网关,需保持一直
另外,如果你在 application.yaml(properties) 中配置了context-path,请删除,这个配置对于Soul而言是无感知的,即你的配置文件中不应出现下面的servlet配置:
server: port: 9092 servlet: context-path: **
如果你在这里配置的:full是false,那么对应3.1.2章节就无需调整,如果是true,直接3.1.2关于SoulPringMvcClient相关注解即可。
3.2 消费者接入Soul
消费者相关配置,和提供者是一致的,这里不再赘述,直接贴出相关代码。
3.2.1 pom
<dependency> <groupId>org.dromara</groupId> <artifactId>soul-spring-boot-starter-client-alibaba-dubbo</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>org.dromara</groupId> <artifactId>soul-spring-boot-starter-client-springmvc</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>org.dromara</groupId> <artifactId>soul-client-springmvc</artifactId> <version>2.2.0</version> </dependency>
3.2.2 Controller
package com.youzha.dubbo.controller; import com.youzha.dubbo.dto.ResultDTO; import lombok.extern.slf4j.Slf4j; import org.dromara.soul.client.springmvc.annotation.SoulSpringMvcClient; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * @author youzhaxiaobo * @version 1.0 * @date 2020/7/4 0004 13:52 * @Desc */ @Slf4j @RestController @RequestMapping("/provider") @SoulSpringMvcClient(path = "/provider/**") public class ProviderController { @GetMapping(value = "/hello", produces = MediaType.APPLICATION_JSON_VALUE) public ResultDTO getUserById(@RequestParam("id") int id) { log.info("id=" + id); if (id > 0) { return new ResultDTO(-1, "获取失败"); } return new ResultDTO(200, "获取成功"); } }
3.2.3 配置文件
soul: # 网关dubbo配置 dubbo: adminUrl: http://127.0.0.1:9093 contextPath: /provider-youzha appName: provider-youzha # 网关http配置 http: adminUrl: http://127.0.0.1:9093 contextPath: /provider appName: provider full: false port: 9091
说明:
- 这里同时暴露出去了dubbo,http两套协议,dubbo对应的就是我们提供在Service层的代码,其变更很小,如下,只是增加了一个注解:@SoulDubboClient
- dubbo,http提供的contextPath的路由前缀,需要保持不同,同时全局唯一(即不能和其他应用一致)
3.3 验证
前提:启动了zookeeper,启动了MySQL。
3.3.1 启动soul-admin
直接启动相关Application即可,登陆控制台查看:localhost:9093,用户名/密码:admin/123456。
成功之后,查看插件,注意这里确保二者开启,且配置项和我吻合:
其中:divide
zk:
{"register":"zookeeper://127.0.0.1:2181"}
3.3.2 启动soul-boostrap
直接启动相关Application即可。
3.3.3 启动soul-provider
直接启动相关Application即可,出现下面的日志则表示注册成功:
3.3.4 启动soul-consumer
直接启动相关Application即可,出现下面的日志则表示注册成功:
注意:
3.3.3,3.3.4启动完成之后,查看soul-admin的网页管理端,应该出现下图:
3.3.5 验证
此时直接通过自身IP访问消费者,地址:http://localhost:9092/consumer/getUserById?id=1,查看日志:
消费者:
提供者:
通过网关访问消费者,地址:http://localhost:9094/consumer/consumer/getUserById?id=1,查看日志:
消费者:
提供者:
直接通过自身IP访问提供者,地址:http://localhost:9091/provider/hello?id=-1
通过网关访问提供者,地址:http://localhost:9094/provider/provider/hello?id=-1
Chrome POST验证provider的dubbo接口
fetch(new Request('http://localhost:9094/provider/provider-youzha/findById',{ method:'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body:"id=1" })).then((resp)=>{console.log(resp)})
注意:
- 通过网关访问,其地址为boostrap对应的:ip+端口
- 访问地址需要加上路由前缀,即配置文件中 soul 模块中的contextPath
- 如果你的项目和soul不部署在同一服务器,请在你的配置文件中追加上该配置(以你实际部署机器IP为准),保证Soul能管理你的服务
- soul.http.host=168.10.54.115