1.声明
当前内容用于本人学习和复习之用,当前内容为,一个服务注册中心,多个服务(权限服务,用户信息服务,支付服务,以及一个app门面),通过app门面方式实现调用多个服务实现操作
2.pom依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.7.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Brixton.SR5</spring-cloud.version>
<!-- <springboot.version>1.3.7.RELEASE</springboot.version> -->
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId>
<version>${springboot.version}</version> <type>pom</type> <scope>import</scope>
</dependency> -->
</dependencies>
</dependencyManagement>
<dependencies>
<!-- spring cloud 的基本配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<!-- <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> -->
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<!-- <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> -->
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- spring boot 的基本配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2.创建服务治理中心(采用Eureka方式实现)
@EnableEurekaServer
@SpringBootApplication
public class AppServiceRegisteryCenter {
public static void main(String[] args) {
SpringApplication.run(AppServiceRegisteryCenter.class, args);
}
}
配置文件application.properties
server.port=1111
server.application.name=eureka-server
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serverUrl.defaultZone=http://127.0.0.1:1112/eureka/
eureka.server.enable-self-preservation=false
eureka.instance.prefer-ip-address=false
3.创建用户信息服务、用户注册服务、权限服务、支付服务
1.用户信息服务
实体类
public class UserInfo {
private String name;
private Integer id;
private List<String> roles;
}
入口类
@RestController
@EnableEurekaClient
@SpringBootApplication
public class UserInfoServiceApp {
// 这里模拟数据库操作
static Map<String, UserInfo> datas = new HashMap<String, UserInfo>();
static {
datas.put("admin", new UserInfo("admin", 1, Arrays.asList("ROLE_ADMIN", "ROLE_USER")));
datas.put("user", new UserInfo("user", 2, Arrays.asList("ROLE_USER")));
datas.put("guest", new UserInfo("guest", 3, Arrays.asList("ROLE_GUEST")));
}
@RequestMapping("/getUserInfoByName")
public String getUserInfoByName(String name) {
System.out.println("调用用户信息服务提供者的内容---》【通过用户名获取用户信息】");
System.out.println("执行当前的通过用户名查询的操作--->" + name);
return datas.get(name).toString();
}
@RequestMapping("/addUserInfo")
public String addUserInfo(UserInfo userInfo) {
System.out.println("调用用户信息服务提供者的内容---》【添加用户信息】");
datas.put(userInfo.getName(), userInfo);
return "添加成功";
}
@RequestMapping("/login")
public String login(String name) {
System.out.println("调用用户信息服务提供者的内容---》【登录操作】");
return "登录" + (datas.containsKey(name) ? "成功" : "失败");
}
public static void main(String[] args) {
SpringApplication.run(UserInfoServiceApp.class, args);
}
}
用户信息模块的配置文件
server.port=2001
spring.application.name=userinfo-service-provider
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
2.用户注册服务
@RestController
@EnableEurekaClient
@SpringBootApplication
public class RegisterServiceApp {
@Autowired
DiscoveryClient client;
// 启用注册验证操作
private boolean validateRegister(String name) {
return name != null;
}
@RequestMapping("/registerUserInfo")
public String registerUserInfo(String name) {
System.out.println("调用用户注册服务提供者的内容");
List<ServiceInstance> instances = client.getInstances("userinfo-service-provider");
ServiceInstance serviceInstance = instances.get(0);
URI uri = serviceInstance.getUri();
String url = uri.toString() + "/addUserInfo";
if (validateRegister(name)) {
ResponseEntity<String> postForEntity = restTemplate.getForEntity(url + "?name={1}", String.class, name);
return postForEntity.getBody();
}
return "注册用户信息失败!";
}
@Autowired
RestTemplate restTemplate;
@Bean
public RestTemplate template() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RegisterServiceApp.class, args);
}
}
配置文件
server.port=2002
spring.application.name=register-service-provider
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
3.权限服务
@RestController
@EnableEurekaClient
@SpringBootApplication
public class PermissServiceApp {
// 模拟数据库操作
private static Map<String, String> permissesData = new HashMap<String, String>();
static {
permissesData.put("ROLE_ADMIN", "INSERT,UPDATE,DELETE,SELECT");
permissesData.put("ROLE_USER", "SELECT,UPDATE");
permissesData.put("ROLE_GUEST", "SELECT");
}
// 一个非常简单的服务,通过角色名称获取权限字符串
@RequestMapping("/getPermissByRoleName")
public String getPermissByRoleName(String roleName) {
System.out.println("调用权限注册服务提供者的内容");
return permissesData.get(roleName);
}
public static void main(String[] args) {
SpringApplication.run(PermissServiceApp.class, args);
}
}
配置文件
server.port=2003
spring.application.name=permiss-service-provider
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
4.支付服务
@RestController
@EnableEurekaClient
@SpringBootApplication
public class PayServiceApp {
@RequestMapping("/pay")
public String pay(String name, Integer money) {
return "用户【" + name + "】,支付【" + money + "】成功!";
}
public static void main(String[] args) {
SpringApplication.run(PayServiceApp.class, args);
}
}
配置文件
server.port=2004
spring.application.name=pay-service-provider
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
4.创建app门面服务(主要通过整个地址访问其他地址的服务)
@RestController
@EnableEurekaClient
@SpringBootApplication
public class AppDemo {
private static final String SUFIX_STRING = "-service-provider";
@Autowired
DiscoveryClient client;
@RequestMapping("getPermiss")
public String getPermiss(String roleName) {
System.out.println("访问App门面中通过角色名称获取用户权限");
List<ServiceInstance> instances = client.getInstances("permiss" + SUFIX_STRING);
ServiceInstance serviceInstance = instances.get(0);
String string = serviceInstance.getUri().toString();
ResponseEntity<String> postForEntity = restTemplate.getForEntity(string + "/getPermissByRoleName?roleName={1}",
String.class, roleName);
String body = postForEntity.getBody();
return body;
}
@RequestMapping("/getUserInfo")
// 用户信息模块
public String getUserInfo(String name) {
System.out.println("访问App门面中通过用户名称获取用户信息");
List<ServiceInstance> instances = client.getInstances("userinfo" + SUFIX_STRING);
ServiceInstance serviceInstance = instances.get(0);
String string = serviceInstance.getUri().toString();
ResponseEntity<String> postForEntity = restTemplate.getForEntity(string + "/getUserInfoByName?name={1}",
String.class, name);
String body = postForEntity.getBody();
return body;
}
@RequestMapping("/login")
public String login(String username) {
System.out.println("访问App门面中通过用户名称来检查登录");
List<ServiceInstance> instances = client.getInstances("userinfo" + SUFIX_STRING);
ServiceInstance serviceInstance = instances.get(0);
String string = serviceInstance.getUri().toString();
ResponseEntity<String> postForEntity = restTemplate.getForEntity(string + "/login?name={1}", String.class,
username);
String body = postForEntity.getBody();
return body;
}
@RequestMapping("/register")
public String register(String name) {
System.out.println("访问App门面中注册用户信息");
List<ServiceInstance> instances = client.getInstances("register" + SUFIX_STRING);
ServiceInstance serviceInstance = instances.get(0);
String string = serviceInstance.getUri().toString();
ResponseEntity<String> postForEntity = restTemplate.getForEntity(string + "/registerUserInfo?name={1}",
String.class, name);
String body = postForEntity.getBody();
return body;
}
@RequestMapping("/pay")
public String pay(String name, Integer money) {
System.out.println("访问App门面中支付服务");
List<ServiceInstance> instances = client.getInstances("pay" + SUFIX_STRING);
ServiceInstance serviceInstance = instances.get(0);
String string = serviceInstance.getUri().toString();
ResponseEntity<String> postForEntity = restTemplate.getForEntity(string + "/pay?name={1}&money={2}",
String.class, name, money);
String body = postForEntity.getBody();
return body;
}
@Autowired
RestTemplate restTemplate;
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(AppDemo.class, args);
}
}
配置文件
server.port=2008
spring.application.name=app-service
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
5.测试访问app门面服务
通过app门面访问注册服务
通过app门面访问支付服务
通过app门面访问用户信息服务
通过app门面访问权限服务
以上都访问成功,通过一个地址实现当前的其他服务的访问操作
6.思考当前的项目中存在的问题
- 我们使用DiscoveryClient的方式实现了手动选择需要的服务实例(如果当前的服务刚好一个都没有或者都宕机了,一定会出现问题),这里还显示提供了服务名称
- 我们使用了RestTemplate方式实现调用,这里还手动编写了访问的url,耦合度太大
如果我们将当前的服务获取方式采用指定方式,但是不是手动选择第一个(采用轮询或者其他方式实现,就可以实现负载均衡(所有服务都不宕机))
如果restTemplate能自动创建url应该是不可能的,并且还需要创建参数并匹配(因为它并不知道这个服务中哪个是我们需要调用的)
7.总结
1.当前项目中使用门面的方式实现了功能的聚集,通过门面方式调用各个服务
2.虽然实现了操作,但是存在一定的问题
以上纯属个人见解,如有问题请联本人!