欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

微服务架构

程序员文章站 2024-03-20 22:19:16
...

本文案例来自 周立博客跟我学Spring-Cloud系列

什么是微服务

微服务其实是一种风格,是将单体应用(所有功能在一个jar包里的应用程序)分为好几各部分,每个部分可以独立运行在不同的服务器中,每个部分还可以用不同的语言开发,服务间的通信采用轻量级通信机制(通常用HTTP资源API)

这种风格有什么优点呢

  • 易于开发
  • 单个服务启动快
  • 技术栈不受限制
  • 按需伸缩

怎么实现微服务架构呢

要想实现微服务,我们就先得解决各个服务间的通信问题,某个节点压力过大怎么办,服务挂了怎么解决,认证授权怎么解决等等问题。

铺垫这么多主角要登场啦,那就是SpringCould,就算有它解决不了的,还可以整合其他框架来解决

第一个springcloud应用

首先了解,服务提供者和服务消费者,简明字意提,提供服务的(如服务器),和使用服务的(如客户端),当然了,所谓的服务消费者和服务生成者是相对而言的,谁提供服务谁就是服务提供者,也有服务器给服务器提供服务的。

微服务架构
如下的案例,来实现上面这张图,用户微服务为服务提供者,电影微服务为服务消费者,小案例到最后可以用电影微服务查到用户微服务的用户信息

先来写个服务提供者(项目名自己起)
先到入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.0.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.txz</groupId>
	<artifactId>microservice-simple-provider-user</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>microservice-simple-provider-user</name>
	<description>服务提供给</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
       
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		 <!-- 数据库 -->
		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
	</dependencies>
	<!--springcloud依赖-->
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Finchley.SR2</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

这个简单案例使用的H2数据库不知道H2数据库没关系,跟着做先就行。

这里使用lombok,IDEA里要导入lombok的插件,它可以帮助我们自动生成getset方法

编写实体类,注解千万不要忘记,包也不要导错

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Column
    private String username;
    @Column
    private String name;
    @Column
    private Integer age;
    @Column
    private BigDecimal bigDecimal;
}

编写Dao

@Repository
public interface UserDao extends JpaRepository<User,Long> {
}

编写controller

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserDao userDao;

    @GetMapping("/{id}")
    public Optional<User> findById(@PathVariable Long id){
        return this.userDao.findById(id);
    }
}

编写Springboot的启动类,Spring Boot2不能像1.x一样,用spring.datasource.schema/data指定初始化SQL脚本,否则与actuator不能共存,所有手动添加

@SpringBootApplication
public class MicroserviceSimpleProviderUserApplication {

	public static void main(String[] args) {
		SpringApplication.run(MicroserviceSimpleProviderUserApplication.class, args);
	}

	@Bean
	ApplicationRunner init(UserDao userDao){
		return args -> {
			User user1 = new User(1L,"xiaoming","小明",20,new BigDecimal(1000.00));
			User user2 = new User(2L,"xiaohong","小红",20,new BigDecimal(1000.00));
			User user3 = new User(3L,"xiaogang","小刚",20,new BigDecimal(1000.00));
			Stream.of(user1,user2,user3).forEach(userDao::save);
		};
	}
}

配置文件

server:
  port: 8000
spring:
  jpa:
    show-sql: true   #让hibernate打印执行的SQL语句

logging:
  level:
    root: INFO
    org.hibernate: INFO
    org.hibernate.type.descriptor.sql.BasicBinder: TRACE
    org.hibernate.type.descriptor.sql.BasicExtractor: TRACE

运行测试,http://localhost:8000/user/1,得到数据

服务消费者 电影微服务

电影微服务,只需要导入,spring web,spring cloud,的包即可

实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    private String username;
    private String name;
    private Integer age;
    private BigDecimal balance;
}

编写collection,这里使用RestTemplate调用用户微服务的API,从而查询指定id的用户信息

@RequestMapping("/movies")
@RestController
public class MovieController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/users/{id}")
    public User findById(@PathVariable Long id){

        //这里用到了RestTemplate的占位符的能力
        User forObject = restTemplate.getForObject("http://localhost:8000/user/{id}", User.class, id);
        return forObject;

    }
}

编写启动类

@SpringBootApplication
public class MicroserviceSimpleConsumerMovieApplication {

	public static void main(String[] args) {
		SpringApplication.run(MicroserviceSimpleConsumerMovieApplication.class, args);
	}
	@Bean
	public RestTemplate restTemplate(){
		return new RestTemplate();
	}
}

测试

用浏览器访问http://localhost:8010/movies/users/1 ,可得到数据

RestTemplate实现了基于HTTP的远程调用,事实上,Spring 5开始,WebFlux提供了Reactive的Web Client:WebClinet使用方式和RestTemplate基本类似,但性能更强,吞吐更好。有兴趣的可前往https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web-reactive.html#webflux-client-builder 了解。

如上我们完成一个简单的单点微服务的实现,该dome有很多问题,有一个http路径在代码中,如果是多个,要改变其端口号,改起来就很麻烦。还有很多比如容错之类的,在之后会 一 一 在该小dome加上