书接上回,我们已经实现了一个简陋的服务调用。在这其中发现了一些问题:
服务地址硬编码写死,不便于维护。
一个tomcat的负载能力有有限。
挂了怎么办。。。。。。等等。
Euraka注册中心:
1.编写EurekaServer,他其实也是一个服务。
模块结构:
1)依赖,pom.xml加入相关依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
2)注解,表明为eureka服务
package com.scbg;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class);
}
}
3)知名端口,否则会与之前的服务(8080)端口冲突.
server:
port: 8082
4)测试启动
浏览器已经能够访问注册中心可视化界面。
但是控制台报错了,而且显示eureka客户端报错。
这是因为:注册中心实际中必然是要搭建集群的,不然这台机器挂掉整个服务都歇菜了。所以这个服务本身也要与其他机器上的eureka之间相互注册,eureka服务端同时也是个客户端,这个客户端在启动后开始找注册中心注册服务。但是我们这里只有一个注册中心,他找不到就报错了。
5)这里我们暂时,让注册中心注册自己。需要在配置文件增加eureka client需要的信息。
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8081/eureka
再次启动服务,发现可以注册成功。首先会报错,然后成功。因为是自己注册自己,开始报错是因为没有完全启动完,下一次心跳完成注册。(心跳,eureka注册中心,自己会间歇性地监听注册的服务,对其进行管理)
6)由上可以看出,这个注册的服务没有名字,配置文件中指定下名字。
spring:
application:
name: eureka-server
齐活。
7)下边就是注册其他服务了。
方法类似:
1》加入eureka客户端依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2》启动类加注解@EnableDiscoveryClient。表明是注册中心的一个客户端,所有的服务无论提供方和消费方对注册中心而言都是客户端。(也可以用eureka那个,但是那就相当于限定注册中心只能用eureka,这个是表明是注册中心的一个客户端,什么注册中心都可以)
package com.scbg;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import tk.mybatis.spring.annotation.MapperScan;
@EnableDiscoveryClient
@SpringBootApplication
@MapperScan("com.scbg.user.mapper")
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class);
}
}
3》配置文件指定信息:
server:
port: 8082
spring:
application:
name: user-service
datasource:
url: jdbc:mysql://localhost:3306/自己的
username: 自己的
password: 自己的
mybatis:
type-aliases-package: com.scbg.user.pojo
eureka:
client:
service-url:
dafaultZone: http://127.0.0.1:8081/eureka
配置consumer-service:
1》加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2》注解
package com.scbg;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerApplication {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class,args);
}
}
3》配置文件
server:
port: 8083
spring:
application:
name: consumer-service
eureka:
client:
service-url:
dafaultZone: http://127.0.0.1:8081/eureka
4》修改controller
package com.scbg.consumer.controller;
import com.scbg.consumer.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
@RequestMapping("consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping("{id}")
public User queryById(@PathVariable("id") Integer id){
//根据id获取实例(因为每个服务会放到多台服务器,可能返回多个实例)
List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
ServiceInstance instance=instances.get(0);
String host=instance.getHost();
int port=instance.getPort();
String url="http://"+host+":"+port+"/user/"+id;
User user= restTemplate.getForObject(url,User.class);
return user;
}
}
8)启动各服务,测试
这里我启动服务报错了,文件太多,我就不一一修改了。我在eureka-server中的
另外两个服务的内容一个是直接复制的,另一个手写的没有多这个空格。导致其无法匹配一直注册不上。这个事我觉得很神奇,配置文件要有一个空格我能理解。留2空格,没有报错还把另一个空格当url地址解析了,我也是不能理解。这个错误找了两个小时,坑死了
成功!