前几篇主要集中在注册中心eureka的使用上,接下来可以创建服务提供者provider来注册到eureka。
demo源码见: https://github.com/ryan-miao/spring-cloud-edgware-demo/tree/master/provider-demo
为了方便版本控制,接下来的项目都是基于https://github.com/ryan-miao/spring-cloud-edgware-demo 这个parent配置的。
创建子moudle provider-demo
创建一个子module,项目名叫provider-demo. 填充springboot和springcloud依赖
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
|
<dependencies>
<!--springboot 依赖start-->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-actuator</artifactid>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-devtools</artifactid>
<optional> true </optional>
</dependency>
<dependency>
<groupid>com.fasterxml.jackson.datatype</groupid>
<artifactid>jackson-datatype-jsr310</artifactid>
</dependency>
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-eureka</artifactid>
</dependency>
<!--springboot 依赖结束-->
<dependency>
<groupid>io.springfox</groupid>
<artifactid>springfox-swagger2</artifactid>
</dependency>
<dependency>
<groupid>io.springfox</groupid>
<artifactid>springfox-swagger-ui</artifactid>
</dependency>
<!--工具类 start-->
<dependency>
<groupid>com.google.guava</groupid>
<artifactid>guava</artifactid>
</dependency>
<dependency>
<groupid>org.projectlombok</groupid>
<artifactid>lombok</artifactid>
<optional> true </optional>
</dependency>
<dependency>
<groupid>net.logstash.logback</groupid>
<artifactid>logstash-logback-encoder</artifactid>
</dependency>
<!--工具类end-->
</dependencies>
|
spring-boot-starter-web
提供web能力,必须spring-boot-starter-actuator
提供项目统计和基础的监控endpoint, 想要使用spring-boot-admin监控就必须添加了 spring-boot-devtools
开发模式 jackson-datatype-jsr310
可以解决java8新的时间apilocaldate解体 spring-cloud-starter-eureka
eureka客户端,负责维护心跳和注册 swagger
提供restful契约 lombok
看起来很清爽的编译级别getter setter工具 guava
大而全的java必备类库 logstash-logback-encoder
想要收集日志到elk,使用这个appender
启动类
1
2
3
4
5
6
7
8
9
|
@enablediscoveryclient
@springbootapplication
public class providerdemoapplication {
public static void main(string[] args) {
springapplication.run(providerdemoapplication. class , args);
}
}
|
@enablediscoveryclient
来启用服务注册
这个providerdemoapplication应该放置于项目包的最外层,因为@springbootappliatin包含了@componentscan的注解,默认扫描本类包下,否则必须手动指定scan。
swagger
swagger就是一个配置类
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
|
@enableswagger2
@configuration
public class swaggerconfiguration {
private apiinfo apiinfo() {
return new apiinfobuilder()
.title( "服务提供者 api" )
.description( "提供用户信息查询" )
.termsofserviceurl( "" )
.version( "1.0.0" )
.build();
}
/**
* 定义api配置.
*/
@bean
public docket api() {
return new docket(documentationtype.swagger_2)
.select()
.apis(requesthandlerselectors.withclassannotation(api. class ))
.build()
.apiinfo(apiinfo());
}
}
|
对于swagger页面的路由,需要我们来引导下:
创建一个controller来导航
1
2
3
4
5
6
7
8
|
@controller
public class homecontroller {
@getmapping (value = { "/api" , "/" })
public string api() {
return "redirect:/swagger-ui.html" ;
}
}
|
来一个controller 接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@api
@restcontroller
@requestmapping ( "/api/v1/users" )
public class usercontroller{
private list<user> users = lists.newarraylist(
new user( 1 , "谭浩强" , 100 , localdate.now()),
new user( 2 , "严蔚敏" , 120 , localdate.now()),
new user( 3 , "谭浩强" , 100 , localdate.now()),
new user( 4 , "james gosling" , 150 , localdate.now()),
new user( 6 , "doug lea" , 150 , localdate.now())
);
@getmapping ( "/" )
public list<uservo> list() {
return users.stream()
.map(u -> new uservo(u.getid(), u.getname(), u.getage(), u.getbirth()))
.collect(collectors.tolist());
}
}
|
一些简单的环境配置
application.yml
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
|
spring:
application:
name: provider-demo
jackson:
serialization:
write_dates_as_timestamps: false
default -property-inclusion: non_null
#服务过期时间配置,超过这个时间没有接收到心跳eurekaserver就会将这个实例剔除
#注意,eurekaserver一定要设置eureka.server.eviction-interval-timer-in-ms否则这个配置无效,这个配置一般为服务刷新时间配置的三倍
#默认90s
eureka.instance.lease-expiration-duration-in-seconds: 15
#服务刷新时间配置,每隔这个时间会主动心跳一次
#默认30s
eureka.instance.lease-renewal-interval-in-seconds: 5
server:
port: 8082
springfox:
documentation:
swagger:
v2:
path: /swagger-resources/api-docs
log:
path: logs
|
application-dev.yml
1
2
3
4
5
6
7
8
9
10
11
|
management:
security:
enabled: false
eureka:
client:
serviceurl:
defaultzone: http: //localhost:8761/eureka/
logstash:
url: localhost: 4560
|
这里需要提一点,由于我集成了logstash, 所以必须安装好logstash, 见elk入门使用。 当然可以跳过,只要不提供logback.xml的配置就行,把依赖中logstash移除即可。
log配置
默认采用logback作为日志框架,简单配置如下,对于不想使用logstash的,移除logstash的appender即可。
在resource下新建logback-spring.xml
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
|
<?xml version= "1.0" encoding= "utf-8" ?>
<configuration scan= "true" scanperiod= "60 seconds" debug= "false" >
<springproperty scope= "context" name= "appname" source= "spring.application.name"
defaultvalue= "unknown" />
<springproperty scope= "context" name= "log.path" source= "log.path"
defaultvalue= "logs" />
<springproperty scope= "context" name= "logstashurl" source= "logstash.url"
defaultvalue= "localhost:4560" />
<include resource= "org/springframework/boot/logging/logback/base.xml" />
<!--输出到控制台-->
<appender name= "console" class = "ch.qos.logback.core.consoleappender" >logginginterceptor
<encoder>
<pattern>%d{hh:mm:ss.sss} %x{req.remotehost} %x{req.requesturi}
${appname} [%thread] %-5level %logger{ 36 } - %msg%n
</pattern>
</encoder>
</appender>
<!--输出到文件-->
<appender name= "file" class = "ch.qos.logback.core.rolling.rollingfileappender" >
<rollingpolicy class = "ch.qos.logback.core.rolling.timebasedrollingpolicy" >
<filenamepattern>${log.path}/${appname}.%d{yyyy-mm-dd}.log</filenamepattern>
</rollingpolicy>
<encoder>
<pattern>%d{hh:mm:ss.sss} ${appname} %x{req.remotehost} %x{req.requesturi}
%x{req.useragent}
%x{req.method} - [%thread] %-5level %logger{ 36 } - %msg%n
</pattern>
</encoder>
</appender>
<!-- 输出到logstash-->
<appender name= "logstash" class = "net.logstash.logback.appender.logstashtcpsocketappender" >
<destination>${logstashurl}</destination>
<encoder charset= "utf-8" class = "net.logstash.logback.encoder.logstashencoder" />
</appender>
<springprofile name= "dev" >
<root level= "info" >
<appender-ref ref= "console" />
<appender-ref ref= "file" />
<appender-ref ref= "logstash" />
</root>
</springprofile>
<springprofile name= "test, prod" >
<root level= "info" >
<appender-ref ref= "file" />
<appender-ref ref= "logstash" />
</root>
</springprofile>
</configuration>
|
启动
确保eureka已启动,admin最好也启动,方便查看app状态,elk的日志系统也最好可以使用。当然,只有eureka是刚需。
编译打包
1
|
mvn clean install package spring-boot:repackage
|
运行main方法,指定profile为dev, 可以在idea中编辑运行配置,添加参数
1
|
--spring.profiles.active=dev
|
或者命令行jar启动
启动后,访问eureka
访问admin
访问provider-demo
暴露我们的api给consumer
既然有服务提供者,必然是为了consumer消费。consumer应该如何消费?手动调用这个http请求即可。前面提到swagger restful契约,就是服务提供者提供请求访问的参数和要求。consumer如果手动去开发这个client必然耗时,而且容易出错。所以,作为服务提供者,理应提供sdk或者client给consumer来用。
在spring cloud技术体系中,远程调用自然是重中之重。目前我找到的具体用法为feign+ribbon+hystrix.
通过feign的声明式接口对接,实现了consumer对provider的调用。ribbon客户端负载均衡,hystrix作健康熔断。
在这里,我们就首先要提供feign的接口了。
把controller的api提炼成一个接口。首先,我们创建一个新的项目
https://github.com/ryan-miao/spring-cloud-edgware-demo/tree/master/provider-api
将这个项目放到provider-demo的依赖列表里
1
2
3
4
5
6
7
|
<!--内部依赖-->
<dependency>
<groupid>com.test</groupid>
<artifactid>provider-api</artifactid>
<version> 0.0 . 1 -snapshot</version>
</dependency>
<!--内部依赖end-->
|
抽离userapi接口道provider-api项目中
1
2
3
4
5
6
|
@requestmapping ( "/api/v1/users" )
public interface userapi {
@getmapping ( "/" )
list<uservo> list();
}
|
在provider-demo的controller里改造如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
@api
@restcontroller
public class usercontroller implements userapi {
private list<user> users = lists.newarraylist(
new user( 1 , "谭浩强" , 100 , localdate.now()),
new user( 2 , "严蔚敏" , 120 , localdate.now()),
new user( 3 , "谭浩强" , 100 , localdate.now()),
new user( 4 , "james gosling" , 150 , localdate.now()),
new user( 6 , "doug lea" , 150 , localdate.now())
);
@override
public list<uservo> list() {
return users.stream()
.map(u -> new uservo(u.getid(), u.getname(), u.getage(), u.getbirth()))
.collect(collectors.tolist());
}
}
|
这样,controller没有变化,只是被抽离了api路径。而独立出来的module provider-api就是我们给consumer提供的client。下一节使用consumer消费。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。
原文链接:http://www.cnblogs.com/woshimrf/p/springcloud-provider.html
相关文章
- 64M VPS建站:是否适合初学者操作和管理? 2025-06-10
- ASP.NET自助建站系统中的用户注册和登录功能定制方法 2025-06-10
- ASP.NET自助建站系统的域名绑定与解析教程 2025-06-10
- 个人服务器网站搭建:如何选择合适的服务器提供商? 2025-06-10
- ASP.NET自助建站系统中如何实现多语言支持? 2025-06-10
- 2025-07-10 怎样使用阿里云的安全工具进行服务器漏洞扫描和修复?
- 2025-07-10 怎样使用命令行工具优化Linux云服务器的Ping性能?
- 2025-07-10 怎样使用Xshell连接华为云服务器,实现高效远程管理?
- 2025-07-10 怎样利用云服务器D盘搭建稳定、高效的网站托管环境?
- 2025-07-10 怎样使用阿里云的安全组功能来增强服务器防火墙的安全性?
快网idc优惠网
QQ交流群
-
详解iOS中position:fixed吸底时的滑动出现抖动的解决方案
2025-05-29 69 -
2025-05-25 98
-
2025-05-25 94
-
解读ASP.NET 5 & MVC6系列教程(5):Configuration配置信息管理
2025-05-29 53 -
2025-05-25 71