spring boot(学习笔记第十一课)
- Session共享,JPA实现自动RESTful
学习内容:
- Session共享
- JPA实现自动RESTful
1. Session共享
-
Session共享面临问题
-
spring boot
默认将session
保存在web server
的内存里面,会产生什么问题呢。
如上图所示,有nginx
作为服务器前置负载均衡器的时候,第一次访问将session
保存在web server 1
中的内存中,但是第二次访问的时候,假如重新定向到web server 4
的时候,将无法正确取得session
。 -
使用
redis
解决问题
使用redis
之后,使每次web server
的session
数据都保存到唯一的redis
的,这样重定向到那个web server
,最后都会从redis
的内存取得,所以每次取得和保存的session
数据都一致。
-
-
Nginx
负载均衡- 创建
nginx server
最好使用sudo -i
。注意,这里使用VMware
进行创建cd /data mkdir nginx wget https://nginx.org/download/nginx-1.27.0.tar.gz cd nginx-1.27.0 yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ ./configure make make install
- 启动
nginx server
- 如果有
process
占用80端口,通过ss -tulnp | grep :80
命令确认。 - 如果有
process
占用80端口,通过ss -tulnp | grep :80
命令确认。 - 之后定位到
$pid
,使用kill -9 $pid
结束进行。注意,这里$pid
意味需要替换的变量
- 如果有
- 尝试访问
nginx server
http://192.168.12.130/
注意,这里采用http
,不能采用https
,如何配置https
在nginx
中需要确认
- 修改
nginx.conf
配置文件upstream finlay.com{ server 192.168.12.1:8080 weight=1; server 192.168.12.1:8081 weight=1; } #gzip on; server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { proxy_pass http://finlay.com; proxy_redirect default; }
- 创建
-
对
spring boot
应用加入session
依赖
加入了这个依赖,spring boot
应用程序自动session
数据保存到redis
的数据库中。<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
-
配置
controller
并且去掉https
- 配置
controller
,在controller
中向session
保存信息之后从session
读取信息。@Value("${server.port}") private String port; @PostMapping("/save") @ResponseBody public String saveName(String name, HttpSession session) { session.setAttribute("name", name); return port; } @GetMapping("get") @ResponseBody public String getName(HttpSession session) { return port + ":" + session.getAttribute("name").toString(); }
- 将
https
配置去掉,因为暂时nginx
没有配置https
。#server.ssl.key-store=classpath:/key/httpskey.p12 #server.ssl.key-alias=hellohttps #server.ssl.key-store-password=123456
- 分别启动
8080
和8081
两个端口,模拟两个server
,进行负载均衡处理server
。java -jar demo-0.0.1-SNAPSHOT.jar --server.port=8080 java -jar demo-0.0.1-SNAPSHOT.jar --server.port=8081
- 配置
-
使用
postman
对nginx
服务器进行模拟发送post请求和get请求。-
发送
post
请求,对session
上设置name
的attribute
。从结果是8080
端口来看, 这里是通过8080
端口的服务器进行session
情报的保存。
-
发送
get请求,对
session上设置
name的
attribute`。
可以看到当
nginx
将请求post
的save
请求上对session
进行设置后,8081
端口的上get
请求,能够马上去的到同样的值,保证服务器端的前置负载均衡器将请求重定向到另一个服务器,取得到的session
情报一致。
-
2. JPA实现自动RESTful
-
这里使用
postgresql
进行实验,对数据源进行配置。spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/springboot spring.datasource.username=finlay spring.datasource.password=123456 spring.jpa.database=postgresql spring.jpa.properties.show-sql=true spring.jpa.properties.hibernate.hbm2ddl.auto=update spring.datasource.driver-class-name=org.postgresql.Driver spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
-
同样引入必要的依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.9</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-rest</artifactId> </dependency>
注意这里加入了
spring-boot-starter-data-rest
,可以在后面看到,这里不需要 在定义自己的controller
代码,spring-boot-starter-data-rest
可以自动生成自己的RESTful
方法。 -
JpaRepository
提供的默认方法
JpaRepository
本身提供了好多方法。尝试查看下代码。@NoRepositoryBean public interface JpaRepository<T, ID> extends ListCrudRepository<T, ID>, ListPagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> { void flush(); <S extends T> S saveAndFlush(S entity); <S extends T> List<S> saveAllAndFlush(Iterable<S> entities); /** @deprecated */ @Deprecated default void deleteInBatch(Iterable<T> entities) { this.deleteAllInBatch(entities); } void deleteAllInBatch(Iterable<T> entities); void deleteAllByIdInBatch(Iterable<ID> ids); void deleteAllInBatch();
-
定义
Entity
类和创建BookReposity
- 定义
Entity
类Book
@Data @Entity(name = "book") public class Book{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; private String author; }
- 继承
JpaRepository<T, ID>
,生成自己的interface
。public interface BookDao extends JpaRepository<Book,Integer> { }
其余的代码需不需要,
spring boot
会自动生成books
(默认的,book
表名加上s),作为默认的RESTful
API的path
。 - 定义
-
利用
postman
进行访问- 利用
post books
进行请求,保存book
的Entity
对象。
- 查看数据库的保存情况。
- 看到增加的
Entity
,spring boot
也给出了访问的url
,进一步使用GET
进行访问。
- 对
books
发出POST
请求,findAll所有的记录。
- 对
book
特定id
发出PUT
请求,修改该记录。
- 对于上面的默认
path(url)
可以进行修改 - 修改整个集合的
path
配置。path
collectionResourceRel
itemResourceRel
@RepositoryRestResource(path = "my_books", collectionResourceRel = "my_books", itemResourceRel = "my_book") public interface BookDao extends JpaRepository<Book, Integer> { }
- 利用