CentOS 安装 mongodb

转:https://www.cnblogs.com/saryli/p/9822819.html

1、下载安装包

curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.12.tgz

2、解压

tar -zxvf mongodb-linux-x86_64-4.0.12.tgz

3、移动到指定位置

mv mongodb-linux-x86_64-4.2.12/ /usr/local/mongodb

4、在/usr/local/mongodb下创建文件夹

mkdir -p /data/dbmkdir /logs

5、在/usr/local/mongodb/bin下新建配置

vi mongodb.conf
#数据文件存放目录
dbpath = /usr/local/mongodb/data/db 
#日志文件存放目录
logpath = /usr/local/mongodb/logs/mongodb.log
#端口
port = 27017
#以守护程序的方式启用,即在后台运行
fork = true
#http访问控制(centos下会此项设置无效:注释掉这个配置或者下载企业评估版)
nohttpinterface = true
auth= true
bind_ip=0.0.0.0

6、环境变量配置

vi /etc/profile
export MONGODB_HOME=/usr/local/mongodb export PATH=$PATH:$MONGODB_HOME/bin

保存后,重启系统配置

source /etc/profile

7、启动
在/usr/local/mongodb/bin下

3mongod -f mongodb.conf 
或
./mongod -f mongodb.conf

8、关闭

#进入控制台
# mongo
> use admin
> db.shutdownServer()
# 命令行
mongod --shutdown
或
./mongod --shutdown

9、开启端口

firewall-cmd --zone=public --add-port=27017/tcp --permanent

查看端口

firewall-cmd --permanent --query-port=27017/tcp

重启防火墙

firewall-cmd --reload

10、创建用户

进入客户端

./mongo

创建用户管理员:

#使用admin数据库
use admin
#创建用户,并分配权限
db.createUser({user:"root",pwd:"root123456",roles:["userAdminAnyDatabase"]})
#给root添加system表的权限
db.grantRolesToUser("root",[{role:"__system",db:"admin"}])
#验证并切换到root用户
db.auth('root','root123456')

以用户管理员身份登录,并切换数据库,创建数据库用户:
切换到test数据库

use test

创建用户名、密码、角色

db.createUser({user:"username",pwd:"@user123456*",roles:[{role:"readWrite",db:"securitydata"}]})

设置mongodb配置中的auth为true(/etc/mongod.conf):

security:authorization: enabled

验证mongodb数据库权限。

db.auth('user','@user123456*')

查看所有用户信息

db.system.users.find()

删除用户

use admin
#验证并切换到root用户
db.auth('root','root123456')
db.system.users.remove({user:"haha"})
db.system.users.find()

11. 非正常关闭修复

# no any other options,不保存损坏数据
$ mongod --repair
# 数据文件路径下包含修复的文件和一个空的mongo.lock文件
$ mongod --dbpath /data/db --repair
# 使用MMAPv1存储引擎还可以指定 --repairpath作为临时的

官方修复文档

Https双向认证,实现系统间通讯双向认证

转自: https://blog.csdn.net/u012977486/article/details/88815621

一、Http

HyperText Transfer Protocol,超文本传输协议,是互联网上使用最广泛的一种协议,所有WWW文件必须遵循的标准。HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全。

使用TCP端口为:80

二、Https

Hyper Text Transfer Protocol over Secure Socket Layer,安全的超文本传输协议,网景公式设计了SSL(Secure Sockets Layer)协议用于对Http协议传输的数据进行加密,保证会话过程中的安全性。

使用TCP端口默认为443

三、SSL协议加密方式

SSL协议即用到了对称加密也用到了非对称加密(公钥加密),在建立传输链路时,SSL首先对对称加密的密钥使用公钥进行非对称加密,链路建立好之后,SSL对传输内容使用对称加密。

对称加密

速度高,可加密内容较大,用来加密会话过程中的消息

公钥加密

加密速度较慢,但能提供更好的身份认证技术,用来加密对称加密的密钥

四、单向认证

Https在建立Socket连接之前,需要进行握手,具体过程如下:

1、客户端向服务端发送SSL协议版本号、加密算法种类、随机数等信息。

2、服务端给客户端返回SSL协议版本号、加密算法种类、随机数等信息,同时也返回服务器端的证书,即公钥证书

3、客户端使用服务端返回的信息验证服务器的合法性,包括:

证书是否过期

发型服务器证书的CA是否可靠

返回的公钥是否能正确解开返回证书中的数字签名

服务器证书上的域名是否和服务器的实际域名相匹配

验证通过后,将继续进行通信,否则,终止通信

4、客户端向服务端发送自己所能支持的对称加密方案,供服务器端进行选择

5、服务器端在客户端提供的加密方案中选择加密程度最高的加密方式。

6、服务器将选择好的加密方案通过明文方式返回给客户端

7、客户端接收到服务端返回的加密方式后,使用该加密方式生成产生随机码,用作通信过程中对称加密的密钥,使用服务端返回的公钥进行加密,将加密后的随机码发送至服务器

8、服务器收到客户端返回的加密信息后,使用自己的私钥进行解密,获取对称加密密钥。 在接下来的会话中,服务器和客户端将会使用该密码进行对称加密,保证通信过程中信息的安全。

五、双向认证

双向认证和单向认证原理基本差不多,只是除了客户端需要认证服务端以外,增加了服务端对客户端的认证,具体过程如下:

1、客户端向服务端发送SSL协议版本号、加密算法种类、随机数等信息。

2、服务端给客户端返回SSL协议版本号、加密算法种类、随机数等信息,同时也返回服务器端的证书,即公钥证书

3、客户端使用服务端返回的信息验证服务器的合法性,包括:

证书是否过期

发型服务器证书的CA是否可靠

返回的公钥是否能正确解开返回证书中的数字签名

服务器证书上的域名是否和服务器的实际域名相匹配

验证通过后,将继续进行通信,否则,终止通信

4、服务端要求客户端发送客户端的证书,客户端会将自己的证书发送至服务端

5、验证客户端的证书,通过验证后,会获得客户端的公钥

6、客户端向服务端发送自己所能支持的对称加密方案,供服务器端进行选择

7、服务器端在客户端提供的加密方案中选择加密程度最高的加密方式

8、将加密方案通过使用之前获取到的公钥进行加密,返回给客户端

9、客户端收到服务端返回的加密方案密文后,使用自己的私钥进行解密,获取具体加密方式,而后,产生该加密方式的随机码,用作加密过程中的密钥,使用之前从服务端证书中获取到的公钥进行加密后,发送给服务端

10、服务端收到客户端发送的消息后,使用自己的私钥进行解密,获取对称加密的密钥,在接下来的会话中,服务器和客户端将会使用该密码进行对称加密,保证通信过程中信息的安全。

六. 代码实现

 1. 多个springboot项目,以两个springboot项目为例,这里暂且叫Client项目,Server项目。

 2. Client项目所在的服务器,Client.p12(客户端证书库) ,Client.cer(客户端公钥);

     Server项目所在的服务器,Server.p12(服务端证书库),Server.cer(服务端公钥);

4.实现步骤

 1. 创建springboot项目,Client ,Server 此处,请自行百度创建如何创建springboot项目。

 2. 使用jdk自带的keytool工具,生成Client和Server端相应的证书,步骤如下:

      a. Client端证书生成步骤:

           1.生成客户端 Client.p12文件    

keytool -genkey -v -alias Client -keyalg RSA -storetype PKCS12 -keystore C:\D\jdk1.8.0_161\Client.p12

设置密码: lq123456
注意事项:生成证书,您的名字与姓氏一项,应该填写服务器的ip(此处应该是域名,但是没有域名,故此处填写服务器ip)
           2 . 导出客户端公钥Client.cer 文件

keytool -keystore C:\D\jdk1.8.0_161\Client.p12  -export -alias Client -file C:\D\jdk1.8.0_161\Client.cer

      b. Server端证书生成步骤

           1.  生成服务端Server.p12文件

keytool -genkey -v -alias Server  -keyalg RSA -storetype PKCS12 -keystore C:\D\jdk1.8.0_161\Server.p12

           设置密码: lq123456
   注意事项:生成证书,您的名字与姓氏一项,应该填写服务器的ip(此处应该是域名,但是没有域名,故此处填写服务器ip)
           2.    导出服务端公钥Server.cer 文件

keytool -keystore C:\D\jdk1.8.0_161\Server.p12 -export -alias Server -file C:\D\jdk1.8.0_161\Server.cer

      c. 将Client端和Server端的公钥文件(.cer文件)导入双方系统的jre运行环境的cacerts证书库

           1.    将客户端公钥导入的服务端jdk信任库

keytool -import -file Client.cer -keystore C:\D\jdk1.8.0_161\jre\lib\security\cacerts –v

           2.    将服务端公钥导入到客户端的jdk信任库

 keytool -import -file Server.cer -keystore  C:\D\jdk1.8.0_161\jre\lib\security\cacerts –v

           3.  将客户端公钥导入到服务端Server.p12证书库

keytool -import -v -file C:\D\jdk1.8.0_161\Client.cer  -keystore C:\D\jdk1.8.0_161\server.p12

      注意事项:此处导入的密码为changeit,默认密码

至此,证书生成完成,证书库导入完成!

       d. 代码实现

            1.Server端

            第一步:在application.properties中添加如下配置:包括本地证书库和受信任证书配置

server.port=8090
server.address=10.119.165.171
server.ssl.key-store=classpath:server.p12
server.ssl.key-store-password=lq123456
server.ssl.key-alias=server
server.ssl.keyStoreType=JKS
 
 
server.ssl.trust-store=classpath:server.p12
server.ssl.trust-store-password=lq123456
server.ssl.client-auth=need
server.ssl.trust-store-type=JKS
server.ssl.trust-store-provider=SUN


             第二步:服务端接口开放


package com.example.server1.controller;
 
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
/**
 * @author lucasliang
 * @date 01/03/2019 3:21 下午
 * @Description
 */
@RestController
@RequestMapping("/server")
public class ServerController {
 
  @RequestMapping("/hello")
  public String getUrlInfo() {
    return "************request https success************";
  }
 
}

     2. Client端

             第一步:在application.properties中添加如下配置:

 server.port=8091
 server.address=10.119.165.171
 server.ssl.key-store=classpath:client.p12
 server.ssl.key-store-password=lq123456
 server.ssl.key-alias=client
 server.ssl.keyStoreType=JKS

第二步:单元测试:

package com.example.client;
 
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
 
/**
 * @author lucasliang
 * @date 04/03/2019 2:13 下午
 * @Description
 */
@SpringBootTest(classes = {Client1ApplicationTests.class})
@RunWith(SpringRunner.class)
public class P12CertTest {
 
  private final static String TEST_URL = "https://10.119.165.171:8090/server/hello";
 
  @Test
  public void getHKVesselTrip() throws Exception {
    KeyStore clientStore = KeyStore.getInstance("PKCS12");
    clientStore
        .load(new FileInputStream("C:\\D\\jdk1.8.0_161\\shuangxiang\\client_original.p12"),
            "lq123456".toCharArray());
 
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(clientStore, "lq123456".toCharArray());
    KeyManager[] kms = kmf.getKeyManagers();
    TrustManagerFactory tmf = TrustManagerFactory
        .getInstance(TrustManagerFactory.getDefaultAlgorithm());
 
    KeyStore trustStore = KeyStore.getInstance("JKS");
    trustStore.load(new FileInputStream("C:\\D\\jdk1.8.0_161\\jre\\lib\\security\\cacerts"),
        "changeit".toCharArray());
    tmf.init(trustStore);
    TrustManager[] tms = tmf.getTrustManagers();
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(kms, tms, new SecureRandom());
    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,
        SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
    CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
    try {
      HttpGet httpget = new HttpGet(TEST_URL);
      System.out.println("executing request" + httpget.getRequestLine());
      CloseableHttpResponse response = httpclient.execute(httpget);
      try {
        HttpEntity entity = response.getEntity();
        if (entity != null) {
          System.out.println(EntityUtils.toString(entity));
        }
      } finally {
        response.close();
      }
    } finally {
 
      httpclient.close();
    }
 
  }
 
}

此时,Client端发送请求到Server端,请求成功,https双向认证完成!

关于Hibernate更新后, 获取的值仍是旧的问题

最近在更新商品库存的时候遇到一个诡异的问题:

1.取出本地商品信息,

2.查询总库库存, 将库存更新到本地

3.再取出商品和库存, 更新库存预警信息

结果在第三步骤出了问题: 取出来的库存是旧的, 不是刚更新的库存???

JAVA类 SkuRepo:

@Modifying
@Query(value = "update Sku set inv=:inv where id=:id")
void updateInv(@Param("id") String id, @Param("inv") int inv);

JAVA类 SkuServie:

//获取sku
Sku slSkuDB = skuRepo.findById("123456").orElse(null);
//获取总库库存
int inv = 0;
........
//更新库存
skuRepo.updateInv(slSkuDB.getId(), inv);
//发送事件
Event.publish(slSkuDB.getId());

JAVA类 SkuInvListener:
//监听库存改变事件
public void onInvChange(String skuId){
Sku slSkuDB = skuRepo.findById("123456").orElse(null);
int inv = slSkuDB.getInv();
................这里获取的库存是旧的
}

问题分析:

经过调试, 发现库存肯定更新成功的.

那么事件监听中, Sku对象不是从数据库取的, 而是上次Hibernate中已有的对象.

而且updateInv并没有更新Hibernate的缓存.

验证:

无奈, 只能断点debug: 发现”SkuServie”获取的Sku和”SkuInvListener”获取的Sku, 指向的Hibernate对象是同一个, 而且inv还是旧值. HQL语句也不会触发缓存更新!!!

处理:

更新库存
  skuRepo.updateInv(slSkuDB.getId(), inv);
改成:
  slSkuDB.setInv(inv);
  skuRepo.save(slSkuDB);

总结:

使用Hibernate一定要实时关注它的缓存问题(一级缓存和二级缓存)

更新对象,最好用Hibernate自带的更新操作, 任何Native SQL和HQL都不会同步到缓存中.